我想创建一个单元测试,以确保一种方法正在使用xUnit和Moq记录错误。该代码在ASP.NET Core 2.1中有效:
//Arrange
var logger = new Mock<ILogger<MyMiddleware>>();
var httpContext = new DefaultHttpContext();
var middleware = new MyMiddleware(request => Task.FromResult(httpContext), logger.Object);
//Act
await middleware.InvokeAsync(httpContext);
//Assert
logger.Verify(x => x.Log(LogLevel.Error, It.IsAny<EventId>(), It.IsAny<FormattedLogValues>(), It.IsAny<Exception>(), It.IsAny<Func<object, Exception, string>>()), Times.Once);
为了验证_logger.LogError("Error message");
调用了middleware.InvokeAsync
。
但是,在ASP.NET Core 3.0中,我无法验证是否正在调用记录器。Microsoft.Extensions.Logging.Internal
不能再被引用,因此FormattedLogValues
不可用。
我尝试将Assert()
改为使用object
而不是FormattedLogValues
,IReadOnlyList<KeyValuePair<string, object>>
因为这FormattedLogValues
是基于(FormattedLogValues.cs)的。
这是我在Visual Studio测试运行程序中收到的错误消息:
Message:
Moq.MockException :
Expected invocation on the mock once, but was 0 times: x => x.Log<object>(LogLevel.Error, It.IsAny<EventId>(), It.IsAny<object>(), It.IsAny<Exception>(), It.IsAny<Func<object, Exception, string>>())
Performed invocations:
ILogger.Log<FormattedLogValues>(LogLevel.Error, 0, Error message, null, Func<FormattedLogValues, Exception, string>)
Stack Trace:
Mock.Verify(Mock mock, LambdaExpression expression, Times times, String failMessage)
Mock`1.Verify(Expression`1 expression, Times times)
Mock`1.Verify(Expression`1 expression, Func`1 times)
MyMiddlewareTests.InvokeAsync_ErrorIsLogged() line 35
--- End of stack trace from previous location where exception was thrown ---
如何验证ASP.NET Core 3.0中正在记录错误?
在aspnet github页面上有一个与此有关的问题。看来问题出在Moq
哪里,他们已经进行了更改以解决此问题。
您将需要升级到Moq 4.13
以获取修复。
他们引入了,It.IsAnyType
以解决内部对象的问题,因此您应该能够更改对的object
引用It.IsAnyType
并像这样编写测试:
logger.Verify(x => x.Log(LogLevel.Error, It.IsAny<EventId>(), It.IsAny<It.IsAnyType>(), It.IsAny<Exception>(), (Func<It.IsAnyType, Exception, string>)It.IsAny<object>()), Times.Once);
注意:最后一个参数需要进行类型转换,因为Moq
当前不支持嵌套类型匹配器。
Moq
可以在此处找到更多详细信息
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句