Serilog ILogger.ForContext выбрасывает исключение NullReferenceException в XUnit Mock - PullRequest
0 голосов
/ 27 апреля 2020

У меня проблема при попытке выполнить модульное тестирование компонентов сигнализатора с помощью 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 Unit он используется как

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

1 Ответ

2 голосов
/ 27 апреля 2020

Это ожидается ... Вы создаете макет ILogger без настройки того, что ForContext должно возвращаться, а затем пытаетесь использовать возвращение ForContext, что, очевидно, null.

* 1006. * Вы должны позвонить Setup на макете, чтобы настроить ForContext для возврата действительного 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);
...