2

I have a test project, in which I setup an http client like this:

public class TestContext : IDisposable
{
    private TestServer _server;
    public HttpClient Client { get; private set; }

    public TestContext() {
        SetUpClient();
    }

    private void SetUpClient()
    {
        _server = new TestServer(new WebHostBuilder()
            .ConfigureAppConfiguration((builderContext, config) => {
                config.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);
            })
            .UseStartup<Startup>()
            .ConfigureServices( services => {
                // ...
            })
        );
        Client = _server.CreateClient();
    }
}

Using the Startup class of the project to be tested.

In my base TestController I was instantiating a console logger like this:

public WSTestController() {
    _log = new LoggerFactory().AddConsole().CreateLogger(this.GetType().Name);
    var testContext = new TestContext();
    _client = testContext.Client;
    // _services = testContext.Services;
}

Now I'm getting the following warning:

controllers\WSTestController.cs(22,20): warning CS0618: 
'ConsoleLoggerExtensions.AddConsole(ILoggerFactory)' is obsolete: 
'This method is obsolete and will be removed in a future version. 
The recommended alternative is AddConsole(this ILoggingBuilder builder).' 

I can't get the logger using DI, any idea how I could work with a builder instead of the soon-to-be-deprecated LoggerFactory???

--

I tried with @max-brodin answer but I get the following error:

The following constructor parameters did not have matching fixture data: ILogger log

I guess that it's because the class WSTestController is not a controller of the server created with the new WebHostBuilder() call, so it's not managed by de dependency injection container.

I also tried exposing the app.serviceProvider and then using this.ServiceProvider.GetService(typeof(ILogger)); but it returns null.

I just can't get a console logger from a class that tests a TestServer

abatishchev
  • 98,240
  • 88
  • 296
  • 433
opensas
  • 60,462
  • 79
  • 252
  • 386
  • 1
    For unit testing, I would recommend using `WebApplicationFactory` fixture (https://learn.microsoft.com/en-us/aspnet/core/test/integration-tests?view=aspnetcore-5.0#customize-webapplicationfactory) rather than creating the `TestServer` directly. – Jeremy Lakeman Mar 24 '21 at 02:54

1 Answers1

0

In order to resolve ILogger<> using DI starting with .Net Core 2.2 you should use register it with loggerbuilder using ConfigureLogging extension method:

_server = new TestServer(new WebHostBuilder()
        .ConfigureAppConfiguration((builderContext, config) => {
            config.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);
        })
        .UseStartup<Startup>()
        .ConfigureServices( services => {
            // ...
        })
        .ConfigureLogging((hostingContext, logging) =>
        {
           logging.AddConsole();
        })
    );

Then you can just inject it in your controller as usual.

public class WSTestController : Controller
{ 
    private readonly ILogger<WSTestController> _logger;

    public WSTestController(ILogger<WSTestController> logger)
    {
       _logger = logger;
    }

}

See details: https://learn.microsoft.com/en-us/aspnet/core/fundamentals/logging/?view=aspnetcore-2.2

Max Brodin
  • 3,903
  • 1
  • 14
  • 23