If you use logging in your application code (and you should) then it would be nice if all that logging info appeared in your unit tests. If you use dotnet core and the default Microsoft.Extensions.Logging then logs will not automatically appear.

Unfortunately the default Debug and Console loggers in the Microsoft.Extensions.Logging family do not flush to standard out quick enough for test frameworks like NUnit to pick up the output because they flush on a background thread for performance. Instead you can force the output to the console (or debug or trace if you prefer) immediately by creating your own implementation of ILogger.

Given you have a class under test that depends on the ILogger interface:

using Microsoft.Extensions.Logging;

public class GlitterBomb : IExplode
{
    private readonly ILogger<MyService> logger;
    private readonly ITrigger trigger;

    public GlitterBomb(ITrigger trigger, ILogger<GlitterBomb> logger)
    {
        this.trigger = trigger;
        this.logger = logger;
    }

   public void ArmBomb()
   {
       logger.LogDebug("Ready to pop!");
       trigger.OnFire += Explode;
   }
   public void Explode()
   {
       logger.LogInfo("Yay unwanted glitter!");
   }
}

Then you can use the following class to create a custom ILogger that will always write to the console for you:

using System;
using Microsoft.Extensions.Logging;

namespace NUnit.Framework
{
    public static class TestLogger
    {
        public static ILogger<T> Create<T>()
        {
            var logger = new NUnitLogger<T>();
            return logger;
        }

        class NUnitLogger<T> : ILogger<T>, IDisposable
        {
            private readonly Action<string> output = Console.WriteLine;

            public void Dispose()
            {
            }

            public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception,
                Func<TState, Exception, string> formatter) => output(formatter(state, exception));

            public bool IsEnabled(LogLevel logLevel) => true;

            public IDisposable BeginScope<TState>(TState state) => this;
        }
    }
}

And then your test looks like this (assuming you are using NUnit and Moq):

[Test]
public void OnFire_SpraysGlitter_WhenTriggered
{
    var mockTrigger = new Mock<ITrigger>();
    ILogger<GlitterBomb> logger = TestLogger.Create<GlitterBomb>();
    var underTest = new GlitterBomb(mockTrigger.Object, testingLogger)

    // trigger and assert for glitter! .....
}

And now you should see all the logging appear in the test output:

test output

Happy logging.

Thanks to Wikipedia for the glitter bomb photo