Search code examples
c#unit-testingdependency-injectionxunit.netnsubstitute

How to verify AddSingleton with special type is received using NSubstitute framework


I want to mock IServiceCollection to check if AddSingleton is called with a specific Interface and concrete type using Nsubstite mocking library and xUnit.

This is my unit test:

[Fact] 
public checkIfServicesAddedTo_DI()
{
    var iServiceCollectionMock = Substitute.For<IServiceCollection>();
    var iConfiguration = Substitute.For<IConfiguration>();
    MatchServicesManager servicesManager = new MatchServicesManager();
    servicesManager.AddServices(iServiceCollectionMock, iConfiguration);

    iServiceCollectionMock.Received(1).AddSingleton(typeof(IMatchManager) , typeof(MatchManager));
}

this is the implementation:

public class MatchServicesManager : IServicesManager
{
    public void AddServices(IServiceCollection services, IConfiguration configuration)
    {
        services.AddSingleton<IMatchManager, MatchManager>();
    }
}

I expect the test to succeed, but it fails with the following error:

NSubstitute.Exceptions.ReceivedCallsException : Expected to receive exactly 1 call matching: Add(ServiceDescriptor) Actually received no matching calls. Received 1 non - matching call(non - matching arguments indicated with '*' characters): Add(*ServiceDescriptor *)


Solution

  • AddSingleton is an extension method on IServiceCollection. This makes it a little more difficult to mock or verify.

    Consider using an actual implementation of the interface and then verify expected behavior after exercising the method under test.

    For example

    public void checkIfServicesAddedTo_DI() {
        //Arrange
        var services = new ServiceCollection();// Substitute.For<IServiceCollection>();
        var configuration = Substitute.For<IConfiguration>();
        MatchServicesManager servicesManager = new MatchServicesManager();
    
        //Act
        servicesManager.AddServices(services, configuration);
    
        //Assert (using FluentAssertions)
        services.Count.Should().Be(1);
        services[0].ServiceType.Should().Be(typeof(IMatchManager));
        services[0].ImplementationType.Should().Be(typeof(MatchManager));
    }