Unit-testing ILogger in ASP.NET Core

Wouter Huysentruit
2 min readNov 3, 2018

--

ASP.NET Core makes it extremely easy to log information, warnings, errors and the like by injecting the generic ILogger<T> interface. However, unit-testing becomes a little bit harder, so let us see why and how we can solve this with ease.

In the examples below, we will be using the mocking framework Moq to verify that a certain message is getting logged.

Service under test

Let’s take a closer look to a service responsible for sending template based e-mails.

Example MailService

Writing the obvious test

Now, we want to make sure that an error is being logged in case _smtpMailer.Send throws an exception.

The first attempt would be to write the test like this:

First, non-working, unit-test attempt

However, since LogError / LogInformation / LogWarning etc are extensions methods, we’re getting the following run-time exception:

Message: System.NotSupportedException : Invalid verify on an extension method.

As it turns out, the ILogger<> interface is pretty simple, but contains a rather complex Log method that is harder to setup or verify in your unit-tests.

Elegant solution

An elegant solution to this problem is to create a small abstract logger class in our unit-test project:

AbstractLogger

…and use a mock of that class in our tests. We can now rewrite the test like this:

Second unit-test attempt

Conclusion

In this post we have seen one way to keep unit-testing using ILogger<T> clean and easy. Of course this is not the only way, but from the many solutions I’ve tried I found this one to be the most elegant and practical solution.

If you have another neat way to get around with tests like this, I’d be glad to hear your solution.

--

--

Wouter Huysentruit
Wouter Huysentruit

Written by Wouter Huysentruit

Software Engineer and Architect focusing on .NET and Microsoft technologies. Microsoft MVP. Practitioner of clean code. #solid #tdd #ddd #cqrs #es #graphql

Responses (1)