Serilog ILogger.ForContext在XUnit Mock中抛出NullReferenceException。

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

当我试图使用Mock对signalr组件进行单元测试时,遇到了一个问题。这里是问题发生的地方

 _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);

日志信息被定义为

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个回答
2
投票

这是预期的... 你正在创建一个模拟的 ILogger 不设 ForContext 应该返回,然后尝试使用返回的 ForContext 这显然 null.

你要打电话 Setup 在您的mock上配置 ForContext 以返回一个有效的 ILogger.

如:.g.

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

然而,看起来你并没有测试任何关于日志的东西,只是创建了一个模拟的 ILogger 来满足被测试类的依赖性。在这种情况下,你根本不需要创建一个mock......。您可以简单地使用 Logger.None 这是个 SilentLogger 什么也不做(不记录也不抛出错误)。

例如

Workstation = new Workstation(Logger.None);
© www.soinside.com 2019 - 2024. All rights reserved.