【问题标题】:How to log TestServer output to the test console如何将 TestServer 输出记录到测试控制台
【发布时间】:2020-12-21 09:32:26
【问题描述】:

我目前正在为我的 ASP .Net Core 5 REST API 编写集成测试 (https://docs.microsoft.com/en-us/aspnet/core/test/integration-tests?view=aspnetcore-5.0)。 API 使用 Serilog 进行日志记录(使用静态 Serilog Logger)。我正在使用 NUnit、Visual Studio 2019、Resharper 运行测试。

我希望在 API 代码运行时记录的所有消息都在测试控制台输出中可见。
例如,如果调用了这个控制器方法:

using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Serilog;

namespace My.Crazy.Api.Controllers
{    
    public sealed class WheelsController : Controller
    {
        [HttpGet("getwheels")]        
        public async Task<IActionResult> Get()
        {            
            Log.Error("An extremely urgent error");         
            return Ok();
        }
    }
}

我希望在测试控制台中显示“一个极其紧急的错误”消息。
然而,这并没有发生。

这是我的 TestServer 设置:

[OneTimeSetUp]
public async Task Setup()
{            
    var hostBuilder = new HostBuilder()
        .ConfigureWebHost(webHost =>
        {
            webHost.UseTestServer();
            webHost.UseStartup<Startup>();  // Startup is the API project's Startup class
    
            Log.Logger = new LoggerConfiguration().WriteTo.Console().CreateLogger();
        });

    var host = await hostBuilder.StartAsync();
    
    _client = host.GetTestClient();
}  

[Test]
public async Task FirstTest() 
{
    var response = await _client.GetAsync("getwheels");
}

我也尝试过使用自定义接收器进行日志记录:

...
// in the test setup
Log.Logger = new LoggerConfiguration().WriteTo.Sink(new CustomSink()).CreateLogger();
...

public class CustomSink : ILogEventSink
{
    public void Emit(LogEvent logEvent)
    {
        var message = logEvent.RenderMessage();
        Console.WriteLine(message);
    }
}

这也不起作用。但是,我已经确认,当 API 代码记录任何消息时,正在调用 Emit 方法。

最后,我尝试使用文件输出:

Log.Logger = new LoggerConfiguration().WriteTo.File("C:\\temp\\test_output.txt").CreateLogger();

按预期工作。但是,我还是想登录控制台。

这可能吗?

不幸的是,对 Serilog 或 NUnit 使用其他任何东西都不是一种选择。

【问题讨论】:

    标签: c# asp.net-core nunit integration-testing serilog


    【解决方案1】:

    所以我会尝试使用带有记录器的自定义记录器提供程序:

    LoggerProvider:

    public class NUnitLoggerProvider : ILoggerProvider
    {
        public ILogger CreateLogger(string categoryName)
        {
            return new NUnitLogger();
        }
    
        public void Dispose()
        {
        }
    }
    

    记录器:

    public class NUnitLogger : ILogger, IDisposable
    {
        public void Dispose()
        {
        }
    
        public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception,
            Func<TState, Exception, string> formatter) {
            var message = formatter(state, exception);
            Debug.WriteLine(message);
        }
    
        public bool IsEnabled(LogLevel logLevel) => true;
    
        public IDisposable BeginScope<TState>(TState state) => this;
    }    
    

    然后在测试文件中:

    var hostBuilder = new HostBuilder()
                .ConfigureWebHost(webHost =>
                {
                    webHost.UseTestServer()
                        .UseStartup<TestStartup>()
                        .ConfigureLogging((hostBuilderContext, logging) =>
                         {
                             logging.Services.AddSingleton<ILoggerProvider, NUnitLoggerProvider>();
                         });
                });            
    

    除了 Debug.WriteLine(message) 你可以使用其他东西来登录。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-08-16
      • 1970-01-01
      • 2015-07-26
      • 2015-07-23
      • 2016-04-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多