Using the Moq framework, it's non-trivial in some cases to verify "Did my logger actually log X message?" The first important note is you can't use Moq on extension methods, so you can't directly check LogWarning
for example. The workaround is to mock the method that the extension method calls..
For example, I want to verify that LogWarning(mymsg)
was logged, but LogWarning
is an extension method. So instead of checking that LogWarning
was called, we check that Log
was called because LogWarning eventually calls Log.
Finally, this SO post showed me how to verify that specific message was logged.
Update: I found Moq.ILogger after implementing this, so you may want to look into that if you're hitting this!
private Mock<ILogger<FooClass>> _mockLogger = _mockLogger = new Mock<ILogger<FooClass>>();
Checking a specific message was logged
_mockLogger.Verify(
logger => logger.Log<It.IsAnyType>( // Must use logger.Log<It.IsAnyType> to sub-out FormattedLogValues, the internal class
LogLevel.Warning, // Match whichever log level you want here
0, // EventId
It.Is<It.IsAnyType>((o, t) => string.Equals("Work item null. Exiting early.", o.ToString())), // The type here must match the `logger.Log<T>` type used above
It.IsAny<Exception>(), // Whatever exception may have been logged with it, change as needed.
(Func<It.IsAnyType, Exception?, string>) It.IsAny<object>()), // The message formatter
Times.Once); // How many times we expect this particular method to be called
Etc. links