Search code examples
c#integration-testing

replace ILogger<T> in servicecollection for integration tests


I have some integration tests and for logging we used

serviceCollection.AddLogging() 

now we need to test that some info is logged in the dependency services where the injected services are ILogger

All the examples I found are for Mock<ILogger>.Object injected directly in the constructor. But that does not apply to me since the logger is for a dependency service and not the constructed one.

Is there an example on how to replace ILogger or ILoggerFactory for unit testing in ServiceCollection.

Edit: how the unit tests look like

var serviceCollection = new ServiceCollection().AddLogging();
....
serviceCollection.Replace(ServiceDescriptor.Singleton<IDependecyService>, IDependecyService, _ => mockService.Object);
....
var serviceProvider = serviceCollection.BuildServiceProvider();
var sut = new Sut(serviceProvider.GetService<IService>(), ....);

The sut does not have any logging injected

IService needs to be injected the IDependecyService

IDependecyService need to be injected the ILogger and this logger I need to mock.

Like I already said the serviceCollection has the ILogger<> and IFactoryLogger but I do not know how to replace them in order to give my mock of ILogger

This is just an example but there are other services with their own ILogger but I need to mock for now only the ILogger the other ILogger<> should remain as AddLogging has done it.


Solution

  • I managed to do this using the ILoggerProvider.

    I mocked this and returned only for the needed category the mocked ILogger

    var mockLoggerProvider = new Mock<ILoggerProvider>();
    mockLoggerProvider.Setup(p => p.CreateLogger(It.IsAny<string>())).Returns<string>(c =>
    {
        if(c == typeof(...).FullName)
        {
            return ...;// mocked logger
        }
        return NullLoggerProvider.Instance.CreateLogger(c);
    });
    new ServiceCollection().AddLogging(l => l.ClearProviders().AddProvider(mockLoggerProvider.Object))