c# – .net core 2.0 ConfigureLogging xunit test
在我的.NET Core 2.0项目中的xUnit集成测试中,我无法在终端中看到同时打印测试结果的日志消息.在WebHost环境中运行代码时,日志将打印到控制台.
这是我在测试构造函数中配置日志记录的方法: var config = new ConfigurationBuilder() .AddJsonFile("appsettings.Tests.json") .Build(); var services = new ServiceCollection(); services.AddLogging(options => { options.AddConfiguration(config.GetSection("Logging")); options.AddConsole(); options.AddDebug(); }); var serviceProvider = services.BuildServiceProvider(); var loggerFactory = serviceProvider.GetService<ILoggerFactory>(); var logger = loggerFactory.CreateLogger("Test"); logger.LogError("From ctor"); 但我没有看到任何日志消息. 解决方法
xUnit在版本2中已更改为不再捕获测试的标准输出:
相反,您现在应该使用an explicit mechanism来写入测试输出.基本上,您不是写入控制台,而是写入特殊的ITestOutputHelper. 当然,ASP.NET Core日志记录默认不支持此输出机制.幸运的是,为测试输出编写日志记录提供程序并不困难.我刚刚实现了一个快速提供程序,并在下面的答案中包含它.你可以像这样使用它: public class Example { private readonly ILogger<Example> _logger; public Example(ITestOutputHelper testOutputHelper) { var loggerFactory = new LoggerFactory(); loggerFactory.AddProvider(new XunitLoggerProvider(testOutputHelper)); _logger = loggerFactory.CreateLogger<Example>(); } [Fact] public void Test() { _logger.LogDebug("Foo bar baz"); } } 请注意,通常应避免在单元测试中创建完整的依赖项注入容器.在单元测试中使用DI通常表明您的单元测试不是单元测试,而是集成测试.在单元测试中,您应该只测试一个特定单元并明确地传递其所有依赖项 – 而不仅仅是作为模拟.正如您在上面的示例中所看到的,创建记录器实际上是一个非常简单的事情,没有DI. 正如所承诺的,这是运行上面显示的代码所需的XunitLoggerProvider和XunitLogger,以及将Microsoft.Extensions.Logging框架与xUnit测试输出集成: public class XunitLoggerProvider : ILoggerProvider { private readonly ITestOutputHelper _testOutputHelper; public XunitLoggerProvider(ITestOutputHelper testOutputHelper) { _testOutputHelper = testOutputHelper; } public ILogger CreateLogger(string categoryName) => new XunitLogger(_testOutputHelper,categoryName); public void Dispose() { } } public class XunitLogger : ILogger { private readonly ITestOutputHelper _testOutputHelper; private readonly string _categoryName; public XunitLogger(ITestOutputHelper testOutputHelper,string categoryName) { _testOutputHelper = testOutputHelper; _categoryName = categoryName; } public IDisposable BeginScope<TState>(TState state) => NoopDisposable.Instance; public bool IsEnabled(LogLevel logLevel) => true; public void Log<TState>(LogLevel logLevel,EventId eventId,TState state,Exception exception,Func<TState,Exception,string> formatter) { _testOutputHelper.WriteLine($"{_categoryName} [{eventId}] {formatter(state,exception)}"); if (exception != null) _testOutputHelper.WriteLine(exception.ToString()); } private class NoopDisposable : IDisposable { public static NoopDisposable Instance = new NoopDisposable(); public void Dispose() { } } } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |