【问题标题】:Serilog ILogger.ForContext throwing NullReferenceException in XUnit MockSerilog ILogger.ForContext 在 XUnit Mock 中抛出 NullReferenceException
【发布时间】:2020-08-11 07:04:52
【问题描述】:

我在尝试使用 Mock 对信号器组件进行单元测试时遇到问题。这就是问题发生的地方

 _logger.LogInformation($"Registering a Station with id: {Id}" +
            $" with status: {Status}" +
            $"{(!string.IsNullOrEmpty(CommandId) ? $", with command: {CommandId}" : "")}", 
            LoggingConstants.Component.MessageHub,
            LoggingConstants.Class.Workstation, 
            !string.IsNullOrEmpty(AppointmentId) ? 
                AppointmentId : LoggingConstants.NoAppointmentId,
            LoggingConstants.NoConfirmationNumber);

LogInformation 定义为

logger.ForContext("Component", (object) component, false).ForContext("Class", (object) @class, 
false).ForContext("AppointmentId", (object) appointmentId, false).ForContext("ConfirmationNumber", 
(object) confirmationNumber, false).Information(message);

在 Xunit 单元测试类中,它被用作

public Mock<ILogger> MockLogger { get; set; }
MockLogger = new Mock<ILogger>();
Workstation = new Workstation(MockLogger.Object);

当单元测试运行时,一旦它遇到 _logger.LogInformation() 消息,它就会抛出一个

"System.NullReferenceException : Object reference not set to an instance of an object.
at LogInformation(ILogger logger, String message, String component, String class, String 
appointmentId, String confirmationNumber)"

为了验证它是否因为 ForContext 而被抛出,使用了这个测试

_logger.Information("a") -> Works
_logger.ForContext("a", "a").Information("a") -> Exception is thrown

【问题讨论】:

    标签: mocking xunit signalr-hub serilog asp.net-core-signalr


    【解决方案1】:

    这是意料之中的...您正在创建 ILogger 的模拟,但没有设置 ForContext 应该返回的内容,然后尝试使用 ForContext 的返回,这显然是 null

    You have to call Setup on your mock to configure ForContext to return a valid ILogger.

    例如

    MockLogger.Setup(x => x.ForContext(It.IsAny<string>(), It.IsAny<string>(), false))
        .Returns(MockLogger.Object);
    

    但是,您似乎没有测试任何有关日志记录的内容,而只是创建了 ILogger 的模拟以满足被测试类的依赖关系。在这种情况下,您根本不必创建模拟...您可以简单地使用 Logger.None,它是一个什么都不做的 SilentLogger(它不记录也不抛出错误)。

    例如

    Workstation = new Workstation(Logger.None);
    

    【讨论】:

    • 我通过添加 MockLogger.Setup(d => d.ForContext(It.IsAny(), It.IsAny(), false)).Returns( MockLogger.Object)在我的模拟记录器初始化下。感谢您的帮助!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-05-30
    • 2015-04-11
    • 2020-11-17
    • 2016-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多