How to Mock ILogger / ILoggerService using Moq

user630190 picture user630190 · Mar 20, 2012 · Viewed 12.1k times · Source

I'm writing some unit tests for my View Model class. The constructor of this class is injected with an ILoggerService. This interface defines 1 method GetLog which returns an ILogger. Something like below where this represents a class that implements ILoggable:-

protected ViewModelBase(ILoggerService loggerService)
    {
        Logger = loggerService.GetLog(this);
    }

I'm trying to unit test my CreateNewOrder method that looks like below:

private void CreateNewOrder(INewOrderViewModel newOrderViewModel)
    {
        Logger.Log("Sending Create New Order Message", LogCategory.Info);
        var createNewOrderMessage = new OrderMessage(newOrderViewModel);
        _eventAggregator.GetEvent<CreateOrderEvent>().Publish(createNewOrderMessage);
    }

How would I go about Mocking the ILoggerService so that a valid Logger is returned? At the moment my Unit test throws a NullReferenceExeception.

I'm using Moq to do my mocking.

I'm imagining I need to do something along the lines of

var loggerService = new Mock<ILoggerService>();
        loggerService.Setup(svc => svc.GetLog(??))

But I can't see how without making my test class implement ILoggable.

Thanks in advance.

Answer

moribvndvs picture moribvndvs · Mar 20, 2012

I'm not sure what the type is of the GetLog method parameter, but I assume it's something like object so the logger service can determine the type requesting a logger. You can use It to mock parameters in a method you are setting up, as seen below.

var logger = new Mock<ILogger>();

var loggerService = new Mock<ILoggerService>();
loggerService.Setup(c => c.GetLog(It.IsAny<object>())
     .Returns(logger.Object);

Then pass logger.Object to whatever method or type needs an ILoggerService.