Search code examples
c#unit-testinglogging.net-core

How to add debug logging to C# .NET Core unit tests


I'm trying to add some simple console logging to my unit tests in ASP.NET Core 2.2 and am having trouble since the logging configuration changed.

I currently have this code, which creates a logger for my class, "DataTests":

// Create logger for our unit tests
var serviceProvider = new ServiceCollection()
    .AddLogging()
    .BuildServiceProvider();

var factory = serviceProvider.GetService<ILoggerFactory>();

var logger = factory.CreateLogger<DataTests>();

But it doesn't log to the debug window, and I can't configure it. I would like to do something like

factory.AddDebug();

But that extension is now obsolete and no longer available. It is replaced by an extension on ILoggingBuilder instead of ILoggerFactory. This is how it's used in file program.cs:

public static void Main(string[] args)
{
    var webHost = new WebHostBuilder()
        .UseKestrel()
        .UseContentRoot(Directory.GetCurrentDirectory())
        .ConfigureAppConfiguration((hostingContext, config) =>
        {
            var env = hostingContext.HostingEnvironment;
            config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
                  .AddJsonFile($"appsettings.{env.EnvironmentName}.json",
                      optional: true, reloadOnChange: true);
            config.AddEnvironmentVariables();
        })
        .ConfigureLogging((hostingContext, logging) =>
        {
            // Requires `using Microsoft.Extensions.Logging;`
            logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
            logging.AddConsole();
            logging.AddDebug();
            logging.AddEventSourceLogger();
        })
        .UseStartup<Startup>()
        .Build();

    webHost.Run();
}

My problem is I don't know how to get the ILoggingBuilder from my unit test class. How can I do this? It's a shame it's so complicated to add a simple logger to a simple unit test class - this should be built in by default I would think.


Solution

  • Use the AddLogging(IServiceCollection, Action<ILoggingBuilder>) overload:

    var serviceProvider = new ServiceCollection()
        .AddLogging(builder => {
            builder.AddDebug();  //<--
    
            //...add other logging configuration as needed
        })
        .BuildServiceProvider();
    
    //...
    

    Which gives access to the builder via a configuration delegate.