【发布时间】:2021-05-24 05:02:21
【问题描述】:
我创建了一个 xUnit 项目来测试这个示例代码
public class ClassToTest
{
private readonly ILogger<ClassToTest> _logger;
public ClassToTest(ILogger<ClassToTest> logger)
{
_logger = logger;
}
public void Foo() => _logger.LogError(string.Empty);
}
我安装了 Moq 来为记录器创建一个模拟实例
public class ClassToTestTests
{
private readonly ClassToTest _classToTest;
private readonly Mock<ILogger<ClassToTest>> _loggerMock;
public ClassToTestTests()
{
_loggerMock = new Mock<ILogger<ClassToTest>>();
_classToTest = new ClassToTest(_loggerMock.Object);
}
[Fact]
public void TestFoo()
{
_classToTest.Foo();
_loggerMock.Verify(logger => logger.LogError(It.IsAny<string>()), Times.Once);
}
}
运行测试时我收到此错误消息
System.NotSupportedException:不支持的表达式:记录器 => logger.LogError(It.IsAny(), new[] { })
System.NotSupportedException 不支持的表达式:logger => logger.LogError(It.IsAny(), new[] { }) 扩展方法 (此处:LoggerExtensions.LogError)可能无法在 setup / 验证表达式。
经过一番研究,我知道所有的日志方法都只是扩展方法。 Moq 无法设置扩展方法。
我想避免为这个问题安装额外的第三方软件包。是否有任何解决方案可以使测试通过?
【问题讨论】:
-
扩展本身调用属于
ILogger接口的其他方法。您可以检查是否调用了该方法。 -
@silkfire 除了扩展方法使用内部类作为状态。因此,如果您想知道/断言实际记录了什么,您就不能......而且 It.IsAny 将不起作用,因为您不能将内部类用于泛型参数。如果您真的有这样的需求,我建议您编写一个自定义 ILogger 实现以在您的测试中使用。您可以将所有消息重定向到一个列表,然后直接声明其内容
-
对此有很多答案,例如stackoverflow.com/a/61741358/2975810