Tips & tricks for unit testing in .NET Core 3: Checking matching and non matching arguments on ILogger

Tips & tricks for unit testing in .NET Core 3: Checking matching and non matching arguments on ILogger

Introduction

You must have been like me for a long time unable to do one thing with ILogger: test the arguments that are passed to its methods during your unit tests. You must most likely use extension methods such as LogDebug, logError etc …… and indeed you can neither mock nor test the arguments passed to them. We will see in this article how to get around this difficulty in order to finally be able to test arguments passed to extension methods of ILogger.

Inside ILogger….

Whatever the extension you’ll use (LogError, LogInformation etc….) internally it uses always the same method. There it is: void Log<TState>

To understand how the parameters are passed from an extension method such as LogDebug to the latter, let’s look at how the calls are chained inside the LoggerExtensions.cs extension class:

Note that through the call sequences of the different overloads of the Log extension method that:

  • The value of the LogLevel parameter depends on the extension method used, here are the possible values
  • EventId is always 0
  • TState corresponds to new FormattedLogValues(message, args) and it’s an object , in other words it’s the formatted message (message template + arguments)
  • Exception is the exception passed (or not) to Log method, for example you can use two overloads of LogError, the first one with an exception in parameter the second one without. so the exception can be null.
  • Func<TState, Exception, string> is a function that you cannot have any control on.

So what can we do with that?

I have built some extensions methods based on previous observations, to compare objects, like Exception, I’m using ExpectedObjects. The mocking library used here is NSubstitute, here we go:

These extensions work like a charm. I just published a Nuget package named “Calzolari.NSubstitute.ILogger.Extensions” that will contains extensions in this article, and very soon packages for other mocking librairies such as Rhino.Mocks, Moq etc….. Please keep posted by checking my Github here: https://github.com/AnthonyGiretti/ILogger-extensions . If you have any suggestions or issues don’t hesitate to contact me!

Happy testing 🙂