测试日志的最佳方法?

问题描述 投票:0回答:1

我的代码用一个ILogger记录了这样的日志。

public class Calculator
{
    private readonly ILogger _logger;

    public Calculator(ILogger<Calculator> logger)
    {
        _logger = logger;
    }

    public int Sum(int x, int y)
    {
        int sum = x + y;

        _logger.LogInformation("The sum of {x} and {y} is {sum}.", x, y, sum);

        return sum;
    }
}

现在我想确定,当我调用Sum(2,3)时,LogInformation包含数字2,3和5。

.net logging moq xunit
1个回答
1
投票

如果是我,我会用 Moq.Contrib.ExpressionBuilders.Logging(日志)。 (免责声明:我是作者)来构建表达方式。它正是为了这个目的而设计的,并提供了一个简单、可读的语句。

loggerMock.Verify(Log.With.LogLevel(LogLevel.Information).And.LogMessage("The sum of {x} and {y} is {sum}.").And.LoggedValue("x", 2).And.LoggedValue("y", 3).And.LoggedValue("sum", 5), Times.Once);

如果你想推出你自己的,你将需要在 Log 方法,并在日志级别和包含 messagelogged 值的只读列表中进行匹配。

日志级别是直接的。要在 messagelogged 值上进行匹配,你需要在方法中添加一个匹配器。TState 参数(第3个参数),如下图所示。

var loggerMock = new Mock<ILogger<Calculator>>();
var logger = loggerMock.Object;
var calculator = new Calculator(logger);

calculator.Sum(2, 3);

loggerMock.Verify(l => l.Log(
    It.Is<LogLevel>(x => x.Equals(LogLevel.Information)),
    It.IsAny<EventId>(),
    It.Is<It.IsAnyType>((o, t) =>
        ((IReadOnlyList<KeyValuePair<string, object>>)o).Last().Value.ToString().Equals("The sum of {x} and {y} is {sum}.") &&
        ((IReadOnlyList<KeyValuePair<string, object>>)o).Any(y => y.Key.Equals("x") && y.Value.Equals(2)) &&
        ((IReadOnlyList<KeyValuePair<string, object>>)o).Any(y => y.Key.Equals("y") && y.Value.Equals(3)) &&
        ((IReadOnlyList<KeyValuePair<string, object>>)o).Any(y => y.Key.Equals("sum") && y.Value.Equals(5))
    ),
    It.IsAny<Exception>(),
    (Func<It.IsAnyType, Exception, string>)It.IsAny<object>()),
Times.Once);

在TState的掩护下,是一个 FormattedLogValues 对象,它实现了 IReadOnlyList<KeyValuePair<string, object>>. FormattedLogValues 在.NET Core 3.*中是内部的,所以你不能访问它。最后一项是 {OriginalFormat} 这是提供给记录仪的日志信息。

© www.soinside.com 2019 - 2024. All rights reserved.