Introduction

Mocking dependencies in development can be a challenge at times especially when you don’t own the interface and the interactions with the interface in code are extension methods. This is the case with ILogger from the base Microsoft logging foundation. The ILogger interface is relatively straight forward however you very rarely interact with it directly. So how do you test that the correct method and parameters have been called to ensure your logging has been correct?

As I’ve written about before you can mock ILogger<> using Moq and have that injected into your sut, or system under test, and check that it is called. However this can get involved and you also need to copy your mock checking code between projects. This is not ideal.

Enter FakeLogger!

FakeLogger gives you full access to all the data which is called against your usage of ILogger in your code and allows you to assert values on it in your tests.

Getting Started

It’s been moved around a bit since the inception but now it can be found in the Microsoft.Extensions.Diagnostics.Testing package and is under the Microsoft.Extensions.Logging.Testing namespace as you’d expect!

Once the nuget package has been referenced in your test project you’re ready to get started using it in your unit tests.

Basic Usage

To demonstrate this we need a sample SUT to work with.

public class DemoService(ILogger<DemoService> logger)
{
    public void LogMe()
    {
        logger.LogInformation("This should be logged.");
    }
}

In the service above we want to test that when the LogMe method is executed the appropriate logging method is called.

We start of by creating an instance of our SUT and this requires instantiating the FakeLogger instance.

        var fakeLogger = new FakeLogger<DemoService>();
        var sut = new DemoService(fakeLogger);

As the FakeLogger<> implements the required interface we can use an instance of it to create our DemoService.

Once the system has been executed in our Act part of the test (as part of our AAA testing flow) we need to assert on the results.

        fakeLogger.LatestRecord.Message.Should().Be("This should be logged.");

The most basic way of doing this is looking at the LatestRecord property on the fake logger. This exposes the last call to the logger instance in the system under test and that’s it for basic usages!

Conclusion

In this post we have reviewed how to use FakeLogger when testing your system under test and require an ILogger implementation. It allows for testing correct logging levels, messages and structured data is specified in your system logging messages.

Are you still rolling your own or are you moving over to FakeLogger?