To assert that logs were generated when writing C# unit tests with Moq:
public static void VerifyLog<T>(this Mock<ILogger<T>> mock, string logMessage, LogLevel level = LogLevel.Error, int times = 1)
where T : class
{
mock.Verify(l =>
l.Log(
level,
It.IsAny<EventId>(),
It.Is<It.IsAnyType>((o, t) =>
o.ToString().Contains(logMessage, StringComparison.InvariantCultureIgnoreCase)),
It.IsAny<Exception>(),
(Func<It.IsAnyType, Exception, string>)It.IsAny<object>()),
Times.Exactly(times)
);
}
public static void VerifyLog<T, TEx>(this Mock<ILogger<T>> mock, string logMessage, LogLevel level = LogLevel.Error, int times = 1)
where T : class
where TEx : Exception
{
mock.Verify(l =>
l.Log(
level,
It.IsAny<EventId>(),
It.Is<It.IsAnyType>((o, t) =>
o.ToString().Contains(logMessage, StringComparison.InvariantCultureIgnoreCase)),
It.IsAny<TEx>(),
(Func<It.IsAnyType, Exception, string>)It.IsAny<object>()),
Times.Exactly(times)
);
}
public static void VerifyLog<T>(this Mock<ILogger<T>> mock, string logMessage, LogLevel level, Times times)
where T : class
{
mock.Verify(l =>
l.Log(
level,
It.IsAny<EventId>(),
It.Is<It.IsAnyType>((o, t) =>
o.ToString().Contains(logMessage, StringComparison.InvariantCultureIgnoreCase)),
It.IsAny<Exception>(),
(Func<It.IsAnyType, Exception, string>)It.IsAny<object>()),
times
);
}
Then
Mock<ILogger<Whatever>> logger = new();
doSomething();
logger.VerifyLog("something was done", LogLevel.Warning);
// or
logger.VerifyLog<ArgumentException>("something that logged an exception", LogLevel.Debug);