c# - 如何检查 ASP.NET Core 3.0 的单元测试中是否记录了错误?

标签 c# asp.net-core moq asp.net-core-3.0 xunit.net

我想创建一个单元测试以确保方法使用 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 中?

最佳答案

an issue在 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 中的更多详细信息可以找到 here

关于c# - 如何检查 ASP.NET Core 3.0 的单元测试中是否记录了错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58294825/

相关文章:

unit-testing - 如何在最小起订量中模拟委托(delegate)

javascript - 为什么我的 js 脚本在从文件引用时无法加载,但在本地使用时却可以工作?

razor - 复杂的自定义标签助手

iis - HTTP 错误 403.14 - 禁止 asp.net 5 和 MVC 6 iis10

c# - 在ASP.Net核心中应用粒度权限限制

c# - 模拟对象的属性以返回来自对象本身的值

.net - 如何查找已传递给我的模拟(Moq 或 Rhino Mocks)接口(interface)上的方法的值?

c# - 如何使我的 C# Windows 应用程序轻量级?

c# - 我的矩形面积和周长在 C# 中为零

c# - ASP.NET Core - 自定义 AspNetCore.Identity 实现不起作用