Search code examples
c#.net.net-coremoqnlog

Mock the logger of NLog and read logged message


Im using NLog 4.5.11 for logging and moq 4.10.1 for mocking.

I have a middleware which writes exception details to the log file using NLog.

I need to unit test middleware in my API project and check the logged message for proper values.

This is how i have declared exception logger :

private static Logger _exceptionLogger = LogManager.GetLogger("ExceptionLogger");

This is how im initializing Logmanager in middlewares constructor :

 LogManager.LoadConfiguration(String.Concat(Directory.GetCurrentDirectory(), "/nlog.config"));

and this is how im logging the exception message :

_exceptionLogger.Error(exceptionMessage);

Is there any way we can do this without actually writing and reading logged message in a file ?


Solution

  • Instead of mocking the logger, it's recommend to use the Memory target in unit tests.

    For example:

    // Arrange
    var config = new NLog.Config.LoggingConfiguration();
    var memoryTarget = new NLog.Targets.MemoryTarget();
    memoryTarget.Layout = "${message}";   // Message format
    config.AddRuleForAllLevels(memoryTarget);
    LogManager.Configuration = config;
    
    // Act
    // Your call
    
    // Assert
    var logEvents = target.Logs;
    // E.g. contains message in logEvents
    

    PS: Please note that in the example above the global LogManager is used, so you can't run the tests in parallel. If you need tests in parallel, create a new LogFactory and pass the LogFactory or created logger to your class / method.