Skip to content

Instantly share code, notes, and snippets.

@skarllot
Last active June 17, 2025 19:03
Show Gist options
  • Save skarllot/49bd3a9eba47040f353344309451d3ec to your computer and use it in GitHub Desktop.
Save skarllot/49bd3a9eba47040f353344309451d3ec to your computer and use it in GitHub Desktop.
Mocking ILogger
using Microsoft.Extensions.Logging;
using Moq;
public static class MockLogger
{
public static Mock<ILogger<T>> Create<T>()
{
var mock = new Mock<ILogger<T>>();
mock.Setup(l => l.IsEnabled(It.IsAny<LogLevel>())).Returns(true);
mock.Setup(x => x.BeginScope(It.IsAny<It.IsAnyType>())).Returns(Mock.Of<IDisposable>());
return mock;
}
public static void VerifyLogging<T>(
this Mock<ILogger<T>> loggerMock,
LogLevel logLevel,
Func<Times> times)
{
VerifyLogging(loggerMock, logLevel, _ => true, times);
}
public static void VerifyLogging<T>(
this Mock<ILogger<T>> loggerMock,
LogLevel logLevel,
Func<string, bool> predicate,
Func<Times> times)
{
loggerMock.Verify(
l => l.Log(
logLevel,
It.IsAny<EventId>(),
It.Is<It.IsAnyType>((o, type) => predicate(o.ToString()!)),
It.IsAny<Exception>(),
It.IsAny<Func<It.IsAnyType, Exception?, string>>()),
times);
}
public static void VerifyLoggingScope<T>(
this Mock<ILogger<T>> loggerMock,
Func<Dictionary<string, object?>, bool> predicate,
Func<Times> times)
{
VerifyLoggingScope(loggerMock, predicate, times());
}
public static void VerifyLoggingScope<T>(
this Mock<ILogger<T>> loggerMock,
Func<Dictionary<string, object?>, bool> predicate,
Times times)
{
loggerMock.Verify(l => l.BeginScope(It.Is<Dictionary<string, object?>>(x => predicate(x))), times);
}
public static void VerifyLoggingScope<T>(
this Mock<ILogger<T>> loggerMock,
string key,
Func<object?, bool> valuePredicate,
Func<Times> times)
{
VerifyLoggingScope(loggerMock, key, valuePredicate, times());
}
public static void VerifyLoggingScope<T>(
this Mock<ILogger<T>> loggerMock,
string key,
Func<object?, bool> valuePredicate,
Times times)
{
VerifyLoggingScope(loggerMock, dict => dict.TryGetValue(key, out var value) && valuePredicate(value), times);
}
}
using Microsoft.Extensions.Logging;
using NSubstitute;
using NSubstitute.ReceivedExtensions;
public static class MockLogger
{
public static ILogger<T> Create<T>()
{
var logger = Substitute.For<ILogger<T>>();
logger.IsEnabled(Arg.Any<LogLevel>()).Returns(true);
return logger;
}
public static void ReceivedLogging<T>(this ILogger<T> logger, int requiredNumberOfCalls, LogLevel logLevel)
{
ReceivedLogging(logger, Quantity.Exactly(requiredNumberOfCalls), logLevel, _ => true);
}
public static void ReceivedLogging<T>(this ILogger<T> logger, Quantity quantity, LogLevel logLevel)
{
ReceivedLogging(logger, quantity, logLevel, _ => true);
}
public static void ReceivedLogging<T>(
this ILogger<T> logger,
int requiredNumberOfCalls,
LogLevel logLevel,
Func<string, bool> predicate)
{
ReceivedLogging(logger, Quantity.Exactly(requiredNumberOfCalls), logLevel, predicate);
}
public static void ReceivedLogging<T>(
this ILogger<T> logger,
Quantity quantity,
LogLevel logLevel,
Func<string, bool> predicate)
{
logger
.Received(quantity)
.Log(
Arg.Is(logLevel),
Arg.Any<EventId>(),
Arg.Is<IReadOnlyList<KeyValuePair<string, object>>>(o => predicate(o.ToString()!)),
Arg.Any<Exception>(),
Arg.Any<Func<IReadOnlyList<KeyValuePair<string, object>>, Exception?, string>>()
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment