ASP.NET Core 3.1 | How to make unit tests with service collection and use NullLogger as ILogger implementation

Viewed 716

I want to make a unit test to test my services but they require ILogger to be dependency injected and I want to store and access them with IServiceProvider. There are NullLogger for situations like that but all of my attempts to add it in the ServiceCollection ends in the following exception:
Unable to resolve service for type 'Microsoft.Extensions.Logging.ILogger 1[MyProject.MyService]' while attempting to activate 'MyProject.MyService'.

public class MyService
{
    private readonly ILogger<MyService> _logger;

    public MyService(ILogger<MyService> logger)
    {
        _logger = logger;
    }
}

public class Tests
{
    private ServiceCollection _services;
    private IServiceProvider _serviceProvider;

    [SetUp]
    public void Setup()
    {
        _services = new ServiceCollection();
        /* ---------------------------\/--------------------------- */

        _services.AddSingleton<ILogger, NullLogger>(); // Doesn't works.
        // _services.AddSingleton<ILoggerFactory, NullLoggerFactory>() Another attempt.

        /* ---------------------------/\--------------------------- */
        _services.AddSingleton<MyService>();
        _serviceProvider = _services.BuildServiceProvider();
    }

    [Test]
    public void SomeTest()
    {
        // Exception will occur on line below.
        var service = _serviceProvider.GetService<MyService>();
        Assert.NotNull(service);
    }
}

What is the proper way to add the NullLogger into the ServiceCollection?

1 Answers

In order to add NullLogger to service collection and allow it's injecting into other services, you should add only the NullLoggerProvider instead of trying to add it like a singleton service.

_services.AddLogging(l => l.AddProvider(NullLoggerProvider.Instance));

Complete setup method:

[SetUp]
public void Setup()
{
    _services = new ServiceCollection();
    _services.AddLogging(l => l.AddProvider(NullLoggerProvider.Instance));
    _services.AddSingleton<MyService>();
    _serviceProvider = _services.BuildServiceProvider();
}
Related