How do I provide ILogger<T> in my unit tests of .NET Core code?

How do I provide ILogger<T> in my unit tests of .NET Core code?

ilogger beginscope
ilogger application insights
serilog ilogger
ilogger example
ilogger c# example
iloggerprovider
microsoft.extensions.logging example c#
asp.net core logging to file

Given a class with a constructor signature of

public Foo(ILogger<Foo> logger) {
    // ...
}

that I want to test, I need some way to provide an ILogger<Foo> in the test. It's been asked before, but the only answer then was to set up a full-blown service registry, configure logging and resolve the logger from there. This seems very overkill to me.

Is there a simple way to provide an implementation of ILogger<T> for testing purposes?

Note: it doesn't have to actually log anything - just not blow up when the subject under test tries to log something.


You have two options:

  1. Create empty implementation of ILogger<Foo> by hand and pass an instance of it to ctor.
  2. Create same empty implementation on the fly using some mocking framework like Moq, NSubstitute, etc.

How do I provide ILogger<T> in my unit tests of .NET Core code , You have two options: Create empty implementation of ILogger<Foo> by hand and pass an instance of it to ctor. Create same empty implementation on the fly using some mocking framework like Moq, NSubstitute, etc. The ILoggerFactory logger factory instance is the boostrapper of the logging system: It is used to attach logger providers and create logger instances - either typed (ILogger<T>) or untyped (ILogger). These logger instances will log to all registered logger providers. Log statements Use structured logs


You can create an instance of ILogger<Foo> using NullLoggerFactory as the factory.

Consider the following controller:

public abstract class Foo: Controller
{
    public Foo(ILogger<Foo> logger) {
        Logger = logger;
    }

    public ILogger Logger { get; private set; }
}

A sample unit test could be:

[TestMethod]
public void FooConstructorUnitTest()
{
    // Arrange
    ILogger<FooController> logger = new Logger<FooController>(new NullLoggerFactory());

    // Act
    FooController target = new FooController(logger);

    // Assert
    Assert.AreSame(logger, target.Logger);
}

Logging in .NET Core and ASP.NET Core, When an ILogger<TCategoryName> object is created, the ILoggerFactory object selects a single rule per provider to apply to that logger. LogInformation(ILogger, EventId, Exception, String, Object[]) Formats and writes an informational log message. LogInformation(ILogger, EventId, String, Object[]) Formats and writes an informational log message. LogInformation(ILogger, Exception, String, Object[]) Formats and writes an informational log message. LogInformation(ILogger, String


Starting from dotnet core 2.0 there's a generic NullLogger<T> class available:

var foo = new Foo(NullLogger<Foo>.Instance);

https://docs.microsoft.com/en-us/dotnet/api/microsoft.extensions.logging.abstractions.nulllogger-1?view=aspnetcore-2.1 (docs) https://github.com/aspnet/Logging/blob/master/src/Microsoft.Extensions.Logging.Abstractions/NullLoggerOfT.cs (source)

Or if you need it as part of your services:

services.AddSingleton<ILoggerFactory, NullLoggerFactory>();

https://docs.microsoft.com/en-us/dotnet/api/microsoft.extensions.logging.abstractions.nullloggerfactory?view=aspnetcore-2.1 (docs)

ILogger Interface (Microsoft.Extensions.Logging), Represents a type used to perform logging. In this article. Definition; Remarks; Methods; Extension Methods; Applies to. Public Function CreateLogger (categoryName As String) As ILogger Parameters. categoryName String. The category name for messages produced by the logger. Returns ILogger.


From the docs for ILogger<T> (emphasis mine):

A generic interface for logging where the category name is derived from the specified TCategoryName type name. Generally used to enable activation of a named ILogger from dependency injection.

So one option would be to change the implementation of the Foo method to take a plain ILogger and use the NullLogger implementation.

Fundamentals of Logging in .NET Core, public interface ILoggerFactory : IDisposable { ILogger CreateLogger(string categoryName); void AddProvider(ILoggerProvider provider); }. The Logging API​  A generic interface for logging where the category name is derived from the specified TCategoryName type name. Generally used to enable activation of a named ILogger from dependency injection.


If you need to verify the calls in addition to just provide the instance, it gets somewhat complicated. The reason is that most calls does not actually belong to the ILogger interface itself.

I have written a more detailed answer here.

Here is a small overview.

Example of a method that I have made to work with NSubstitute:

public static class LoggerTestingExtensions
{
    public static void LogError(this ILogger logger, string message)
    {
        logger.Log(
            LogLevel.Error,
            0,
            Arg.Is<FormattedLogValues>(v => v.ToString() == message),
            Arg.Any<Exception>(),
            Arg.Any<Func<object, Exception, string>>());
    }

}

And this is how it can be used:

_logger.Received(1).LogError("Something bad happened");   

Provide an implementation of ILogger from Microsoft.Extensions , I have created my own project for it, copied the same buildup as from the Debug logger, and called it Microsoft.Extensions.Logging.Raven , for  var mock = new Mock<ILogger<BlogController>> (); ILogger<BlogController> logger = mock.Object; //or use this short equivalent logger = Mock.Of<ILogger<BlogController>> () var controller = new BlogController(logger); You probably will need to install Microsoft.Extensions.Logging.Abstractions package to use ILogger<T>.


Logging, Each logger provides its own set of extension methods to ILoggerFactory . The console, debug, and event log loggers allow you to specify the minimum logging​  Thanks for contributing an answer to Stack Overflow! Please be sure to answer the question. Provide details and share your research! But avoid … Asking for help, clarification, or responding to other answers. Making statements based on opinion; back them up with references or personal experience. To learn more, see our tips on writing great


Microsoft.Extensions.Logging, Part 2: Types, ILoggerProvider is a way to extend Microsoft.Extensions.Logging by implementation. However, you don't ever want to consume a logger provider  If a logging data store is slow, don't write to it directly. Consider writing the log messages to a fast store initially, then moving them to the slow store later. For example, when logging to SQL Server, don't do so directly in a Log method, since the Log methods are synchronous. Instead, synchronously add log messages to an in-memory queue and have a background worker pull the messages out of the queue to do the asynchronous work of pushing data to SQL Server.


How to work with logging in ASP.Net Core, public interface ILoggerFactory : IDisposable { ILogger CreateLogger(string categoryName); void AddProvider(ILoggerProvider provider); }. These discoveries led the U.S. Centers for Disease Control and Prevention (CDC) to do an about-face on face masks. The CDC updated its guidance to recommend widespread use of simple cloth face coverings to help prevent transmission of the virus by people who have COVID-19 but don't know it.