我正在尝试使用 nsubstitute 来测试 Microsoft.Extensions.Logging 中的 ILogger。
正如这里所说:
无法测试 ILogger
public class TestsUsingMoq
{
[Test]
public void MyMethod_String_LogsError()
{
// Arrange
var logger = Mock.Of<ILogger<MyClass>>();
var myClass = new MyClass(logger);
var message = "a message";
// Act
myClass.MyMethod(message);
//Assert
Mock.Get(logger)
.Verify(l => l.Log(LogLevel.Error,
It.IsAny<EventId>(),
It.Is<It.IsAnyType>((o, t) => ((IReadOnlyList<KeyValuePair<string, object>>) o).Last().Value.ToString().Equals(message)),
It.IsAny<Exception>(),
(Func<It.IsAnyType, Exception, string>) It.IsAny<object>()),
Times.Once);
}
}
我尝试通过 nsubstitute 在我的代码中做类似的事情,但它失败了,因为 (Arg.Is<-object->) 不等于起订量中的It.Is
_logger.IsEnabled(Arg.Any<LogLevel>()).Returns(true);
_logger.Received().Log(
Arg.Any<LogLevel>(),
Arg.Any<EventId>(),
Arg.Is<object>(o => o.ToString().Contains("bad")),
null,
Arg.Any<Func<object, Exception, string>>());
一个潜在的解决方法是获取呼叫信息并手动处理。例如:
// Assuming this object contains the expected key-value pairs that are logged:
var expectedLogState = new List<KeyValuePair<string, object>>();
loggerMock.ReceivedCalls().Should().NotBeEmpty();
var logInput = loggerMock.ReceivedCalls().First().GetArguments();
logInput[0].Should().Be(LogLevel.Error);
(logInput[2] as IEnumerable<KeyValuePair<string, object>>).Should().Contain(expectedLogState);
从版本 5.1.0 开始,NSubstitute 支持 Arg.AnyType 来匹配具有通用参数的调用。 https://github.com/nsubstitute/NSubstitute/releases/tag/v5.1.0