TestSuite.TUnit.AutoFixture.NSubstitute 1.0.0

The owner has unlisted this package. This could mean that the package is deprecated, has security vulnerabilities or shouldn't be used anymore.
dotnet add package TestSuite.TUnit.AutoFixture.NSubstitute --version 1.0.0
                    
NuGet\Install-Package TestSuite.TUnit.AutoFixture.NSubstitute -Version 1.0.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="TestSuite.TUnit.AutoFixture.NSubstitute" Version="1.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="TestSuite.TUnit.AutoFixture.NSubstitute" Version="1.0.0" />
                    
Directory.Packages.props
<PackageReference Include="TestSuite.TUnit.AutoFixture.NSubstitute" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add TestSuite.TUnit.AutoFixture.NSubstitute --version 1.0.0
                    
#r "nuget: TestSuite.TUnit.AutoFixture.NSubstitute, 1.0.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package TestSuite.TUnit.AutoFixture.NSubstitute@1.0.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=TestSuite.TUnit.AutoFixture.NSubstitute&version=1.0.0
                    
Install as a Cake Addin
#tool nuget:?package=TestSuite.TUnit.AutoFixture.NSubstitute&version=1.0.0
                    
Install as a Cake Tool

TestSuite.TUnit.AutoFixture.NSubstitute

NSubstitute auto-mocking integration for TestSuite.TUnit.AutoFixture.

Installation

dotnet add package TestSuite.TUnit.AutoFixture.NSubstitute

This package automatically includes:

  • TestSuite.TUnit.AutoFixture (core library)
  • AutoFixture.AutoNSubstitute
  • NSubstitute

Features

  • [AutoNSubstituteData] - Automatically mocks interfaces and generates test data
  • [InlineAutoNSubstituteData] - Combines explicit values with auto-mocked interfaces
  • Frozen Mocks - Use [Frozen] with mocked interfaces
  • Full NSubstitute API - Configure mocks with Returns(), Received(), etc.
  • xUnit-Compatible - Same patterns as AutoFixture.AutoNSubstitute

Usage

Basic Auto-Mocking with [AutoNSubstituteData]

The [AutoNSubstituteData] attribute automatically mocks all interfaces:

using TestSuite.TUnit.AutoFixture.NSubstitute;
using TUnit.Core;
using NSubstitute;

public interface IRepository
{
    string GetData();
}

[Test]
[AutoNSubstituteData]
public void Test_AutomaticallyMocksInterfaces(IRepository repository)
{
    // Interface is automatically mocked by NSubstitute
    repository.Should().NotBeNull();

    // Configure the mock
    repository.GetData().Returns("test data");

    // Use the mock
    var result = repository.GetData();
    result.Should().Be("test data");
}

Combining Mocks and Generated Types

public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}

[Test]
[AutoNSubstituteData]
public void Test_MocksAndGeneratedTypes(
    IRepository mockRepository,
    string autoText,
    int autoNumber,
    Person autoPerson)
{
    // Interfaces are mocked
    mockRepository.Should().NotBeNull();

    // Primitives are auto-generated
    autoText.Should().NotBeNull();
    autoNumber.Should().NotBe(0);

    // Complex types are auto-generated
    autoPerson.Should().NotBeNull();
    autoPerson.Name.Should().NotBeNull();
}

Frozen Mocks

Use [Frozen] to inject the same mock instance into all consumers:

public interface IService
{
    string GetData();
}

public class Service
{
    private readonly IService _service;

    public Service(IService service)
    {
        _service = service;
    }

    public string ProcessData()
    {
        return _service.GetData();
    }
}

[Test]
[AutoNSubstituteData]
public void Test_FrozenMock(
    [Frozen] IService service,
    Service sut)
{
    // Configure the frozen mock
    service.GetData().Returns("frozen data");

    // Act - sut uses the same frozen mock
    var result = sut.ProcessData();

    // Assert
    result.Should().Be("frozen data");
    service.Received(1).GetData();
}

Multiple Consumers, Same Mock

public class Consumer
{
    public IService Service { get; }

    public Consumer(IService service)
    {
        Service = service;
    }
}

[Test]
[AutoNSubstituteData]
public void Test_MultipleFrozenMockInjections(
    [Frozen] IService service,
    Consumer consumer1,
    Consumer consumer2)
{
    // All consumers receive the same frozen mock
    consumer1.Service.Should().BeSameAs(service);
    consumer2.Service.Should().BeSameAs(service);
}

Inline Auto-Mocking with [InlineAutoNSubstituteData]

Combine explicit values with auto-mocked interfaces:

[Test]
[InlineAutoNSubstituteData("explicit value")]
public void Test_InlineWithMocks(
    string explicitValue,
    IRepository autoMock,
    Person autoPerson)
{
    // First parameter is explicit
    explicitValue.Should().Be("explicit value");

    // Interfaces are auto-mocked
    autoMock.Should().NotBeNull();
    autoMock.GetData().Returns("mocked");
    autoMock.GetData().Should().Be("mocked");

    // Complex types are auto-generated
    autoPerson.Should().NotBeNull();
}

Multiple Test Cases with Mocks

[Test]
[InlineAutoNSubstituteData(100)]
[InlineAutoNSubstituteData(200)]
public void Test_MultipleTestCasesWithMocks(
    int explicitId,
    IRepository repository)
{
    // Each test case has its own mock instance
    repository.GetData().Returns($"data-{explicitId}");

    var result = repository.GetData();

    result.Should().Be($"data-{explicitId}");
    explicitId.Should().BeOneOf(100, 200);
}

NSubstitute Features

Configuring Return Values

[Test]
[AutoNSubstituteData]
public void Test_ConfiguringReturns(IService service)
{
    // Simple return value
    service.GetData().Returns("test");

    // Conditional returns
    service.GetData("key1").Returns("value1");
    service.GetData("key2").Returns("value2");

    // Computed returns
    service.GetData(Arg.Any<string>()).Returns(x => $"Result for {x[0]}");
}

Verifying Method Calls

[Test]
[AutoNSubstituteData]
public void Test_VerifyingCalls(IService service)
{
    // Arrange
    service.GetData().Returns("test");

    // Act - call multiple times
    service.GetData();
    service.GetData();
    service.GetData();

    // Assert - verify call count
    service.Received(3).GetData();

    // Verify with argument matchers
    service.GetData("specific");
    service.Received(1).GetData("specific");
}

Argument Matchers

[Test]
[AutoNSubstituteData]
public void Test_ArgumentMatchers(IService service)
{
    // Any argument
    service.GetData(Arg.Any<string>()).Returns("default");

    // Specific conditions
    service.GetData(Arg.Is<string>(x => x.StartsWith("test"))).Returns("matched");

    // Multiple conditions
    service.GetData(
        Arg.Is<string>(x => x.Length > 5),
        Arg.Any<int>()
    ).Returns("complex match");
}

Throwing Exceptions

[Test]
[AutoNSubstituteData]
public void Test_ThrowingExceptions(IService service)
{
    // Configure mock to throw
    service.GetData()
        .Returns(x => throw new InvalidOperationException("Test exception"));

    // Act & Assert
    Action act = () => service.GetData();
    act.Should().Throw<InvalidOperationException>()
       .WithMessage("Test exception");
}

Advanced Scenarios

Multiple Interface Implementations

public interface IInterface1
{
    void Method1();
}

public interface IInterface2
{
    void Method2();
}

public class MultiInterfaceClass : IInterface1, IInterface2
{
    public void Method1() { }
    public void Method2() { }
}

[Test]
[AutoNSubstituteData]
public void Test_MultipleInterfaces(
    IInterface1 interface1,
    IInterface2 interface2,
    MultiInterfaceClass concrete)
{
    // All interfaces are mocked
    interface1.Should().NotBeNull();
    interface2.Should().NotBeNull();

    // Concrete class is generated
    concrete.Should().NotBeNull();

    // Configure and verify mocks
    interface1.When(x => x.Method1()).Do(_ => { });
    interface2.When(x => x.Method2()).Do(_ => { });

    interface1.Method1();
    interface2.Method2();

    interface1.Received(1).Method1();
    interface2.Received(1).Method2();
}

Frozen with Matching Strategies

Combine frozen mocks with matching strategies:

public interface IService { }
public class ConcreteService : IService { }

public class Consumer
{
    public IService Service { get; }

    public Consumer(IService service)
    {
        Service = service;
    }
}

[Test]
[AutoNSubstituteData]
public void Test_FrozenWithImplementedInterfaces(
    [Frozen(Matching.ImplementedInterfaces)] ConcreteService concrete,
    Consumer consumer)
{
    // With ImplementedInterfaces, concrete is frozen for IService too
    consumer.Service.Should().BeSameAs(concrete);
}

Complex Dependency Graphs

public class MultiDependencyService
{
    public IRepository Repository { get; }
    public ILogger Logger { get; }
    public ICache Cache { get; }

    public MultiDependencyService(
        IRepository repository,
        ILogger logger,
        ICache cache)
    {
        Repository = repository;
        Logger = logger;
        Cache = cache;
    }
}

[Test]
[AutoNSubstituteData]
public void Test_ComplexDependencyGraph(
    [Frozen] IRepository repository,
    [Frozen] ILogger logger,
    [Frozen] ICache cache,
    MultiDependencyService sut)
{
    // All frozen mocks are injected
    sut.Repository.Should().BeSameAs(repository);
    sut.Logger.Should().BeSameAs(logger);
    sut.Cache.Should().BeSameAs(cache);

    // Configure and verify
    repository.GetData().Returns("data");
    cache.TryGet(Arg.Any<string>(), out Arg.Any<object>()).Returns(false);

    // Use sut...
}

ConfigureMembers Setting

This library uses ConfigureMembers = false by default, which means NSubstitute won't automatically configure property getters and setters.

If you need automatic property configuration:

public class CustomAutoNSubstituteDataAttribute : AutoDataAttribute
{
    public CustomAutoNSubstituteDataAttribute()
        : base(() =>
        {
            var fixture = new Fixture();
            fixture.Customize(new AutoNSubstituteCustomization
            {
                ConfigureMembers = true  // Enable automatic property configuration
            });
            return fixture;
        })
    {
    }
}

[Test]
[CustomAutoNSubstituteData]
public void Test_WithConfiguredMembers(IService service)
{
    // Properties are automatically configured
}

Important Notes

Multiple Mock Instances

Each parameter gets its own mock instance unless marked with [Frozen]:

[Test]
[AutoNSubstituteData]
public void Test_MultipleMocks(
    IService service1,
    IService service2)
{
    // These are DIFFERENT mock instances
    service1.Should().NotBeSameAs(service2);

    // Each can be configured independently
    service1.GetData().Returns("mock1");
    service2.GetData().Returns("mock2");

    service1.GetData().Should().Be("mock1");
    service2.GetData().Should().Be("mock2");
}

Concrete Types Not Mocked

Only interfaces and abstract classes are mocked. Concrete types are generated by AutoFixture:

public class ConcreteClass
{
    public virtual string GetData() => "real";
}

[Test]
[AutoNSubstituteData]
public void Test_ConcreteTypesNotMocked(ConcreteClass concrete)
{
    // This is NOT a mock - it's a real instance
    concrete.Should().NotBeNull();
    concrete.GetData().Should().Be("real");
}

To mock concrete classes with virtual members, use Substitute.ForPartsOf<T>() manually.

Examples

See the test project for comprehensive examples:

Requirements

  • .NET 10.0 or later
  • TUnit.Core 1.10.0 or later
  • TestSuite.TUnit.AutoFixture 1.0.0 or later
  • AutoFixture.AutoNSubstitute 4.18.1 or later
  • NSubstitute 5.1.0 or later

NSubstitute Documentation

For complete NSubstitute documentation, see:

License

MIT License - see LICENSE file for details.

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated

See RELEASE_NOTES.md for detailed release notes.