I want to be able to do integration tests as defined in introduction to integration tests and then assert the log messages produced.
The problem with testing the ILogger
interface is that in itself it's a very small interface and most of the methods you use are actually extension methods. This makes it harder to mock/substitute on your tests.
You can research online and you will find many articles on this subject such as:
- Log[Severity] Extension Methods Make Unit Testing Logging Behavior Difficult
- How to test logging when using Microsoft.Extensions.Logging
- Tips & tricks for unit testing in .NET Core 3: Checking matching and non matching arguments on ILogger
For now I believe that using MELT is the best approach to take.
From MELT's README:
MELT is a free, open-source, testing library for the .NET Standard Microsoft Extensions Logging library. It is a solution to easily test logs.
It is a repackaging with a sweetened API and some omissions of Microsoft.Extensions.Logging.Testing, a library used internally in ASP.NET Core for testing the logging, given that there is currently no plan to offer an official package for it.
MELT will work for unit tests and integration tests. It also integrates with popular logging frameworks such as Serilog and NLog.
See METL's README to understand how to configure it for unit tests and for integration tests
- When running tests using MELT and Serilog make sure the those tests do NOT run in parallel. For instance, using xUnit that can easily be configured via the
Collection
attribute. The reason why this is needed is because the Serilog logger is setup on a static global property and if tests run in parallel you will get incorrect results.
Analyse the code of the demo app TestingLogsWithSerilog to gain a better understanding of how to test logs in integration tests using Serilog and MELT.