I am having an issue when trying to unit test signalr components using Mock. Here is where the issue occurs
_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 is defined as
logger.ForContext("Component", (object) component, false).ForContext("Class", (object) @class,
false).ForContext("AppointmentId", (object) appointmentId, false).ForContext("ConfirmationNumber",
(object) confirmationNumber, false).Information(message);
In the Xunit Unit test class, it is being used as
public Mock<ILogger> MockLogger { get; set; }
MockLogger = new Mock<ILogger>();
Workstation = new Workstation(MockLogger.Object);
When the unit test is run, once it hits that _logger.LogInformation() message, it throws a
"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)"
To verify that it is being thrown because of the ForContext, this test was used
_logger.Information("a") -> Works
_logger.ForContext("a", "a").Information("a") -> Exception is thrown
That's expected... You are creating a mock of ILogger
without setting up what ForContext
should return, and then trying to use the return of ForContext
which is obviously null
.
You have to call Setup
on your mock to configure ForContext
to return a valid ILogger
.
e.g.
MockLogger.Setup(x => x.ForContext(It.IsAny<string>(), It.IsAny<string>(), false))
.Returns(MockLogger.Object);
However, it looks you are not testing anything about logging and is just creating a mock of ILogger
to satisfy the dependency of the class being tested. In that case, you don't have to create a mock at all... You can simply use Logger.None
which is a SilentLogger
that does nothing (it doesn't log nor throws errors).
e.g.
Workstation = new Workstation(Logger.None);