如何测试asp.net核心内置的Ilogger

ari*_*its 32 c# logging unit-testing moq asp.net-core

我想验证记录的一些日志.我使用的是asp.net核心内置的ILogger,并使用asp.net内核的DI注入它:

private readonly ILogger<InvoiceApi> _logger;

public InvoiceApi(ILogger<InvoiceApi> logger)
{
    _logger = logger;
}
Run Code Online (Sandbox Code Playgroud)

然后我用它像: _logger.LogError("error));

我像往常一样通过以下方式嘲笑它(使用moq):

MockLogger = new Mock<ILogger<InvoiceApi>>();
Run Code Online (Sandbox Code Playgroud)

并将其注入服务中以供测试:

new InvoiceApi(MockLogger.Object);
Run Code Online (Sandbox Code Playgroud)

然后尝试验证:

MockLogger.Verify(m => m.LogError(It.Is<string>(s => s.Contains("CreateInvoiceFailed"))));
Run Code Online (Sandbox Code Playgroud)

但它抛出:

对非虚拟(在VB中可覆盖)成员的验证无效:m => m.LogError

那么,如何验证记录的日志?

khe*_*ang 63

正如@Nkosi已经说过的那样,你无法模拟扩展方法.你应该嘲笑,是ILogger.Log方法,其LogError调用到.它使验证码有点笨拙,但它应该工作:

MockLogger.Verify(
    m => m.Log(
        LogLevel.Error,
        It.IsAny<EventId>(),
        It.Is<FormattedLogValues>(v => v.ToString().Contains("CreateInvoiceFailed")),
        It.IsAny<Exception>(),
        It.IsAny<Func<object, Exception, string>>()
    )
);
Run Code Online (Sandbox Code Playgroud)

(不确定这是否编译,但你得到了要点)

  • 太糟糕了。看起来新版本的 Moq (v4.13) 允许您使用 `It.IsAnyType` 而不是 `FormattedLogValues`,因此您仍然可以在 3.0 中模拟它。请参阅 https://github.com/aspnet/Extensions/issues/1319。 (6认同)
  • 由于FormattedLogValues进入内部,因此在.NET Core 3.0中中断。 (2认同)
  • `It.IsAnyType` 工作!这是上面提到的链接中的一个有效解决方案: `_loggerMock.Verify(x =&gt; x.Log(LogLevel.Warning, It.IsAny&lt;EventId&gt;(), It.IsAny&lt;It.IsAnyType&gt;(), It.IsAny &lt;Exception&gt;(), (Func&lt;It.IsAnyType, Exception, string&gt;)It.IsAny&lt;object&gt;()))));` (2认同)

Tol*_*han 9

在对 .net core 3.1 FormattedLogValues 进行一些升级后成为内部的。我们不能再访问它了。我做了一些更改的扩展方法。扩展方法的一些示例用法:

mockLogger.VerifyLog(Times.Once);
Run Code Online (Sandbox Code Playgroud)
mockLogger.VerifyLog(Times.Once);
Run Code Online (Sandbox Code Playgroud)


ssm*_*ith 6

我写了一篇简短的文章,展示了各种方法,包括模拟底层的Log()方法,如此处其他答案所述。本文包括一个完整的GitHub存储库,其中包含每个不同的选项。最后,我的建议是使用您自己的适配器,而不是直接使用ILogger类型,如果您需要能够测试它是否正在被调用的话。

https://ardalis.com/testing-logging-in-aspnet-core