【问题标题】:How to add debug logging to C# .NET Core unit tests如何将调试日志记录添加到 C# .NET Core 单元测试
【发布时间】:2019-07-16 17:27:12
【问题描述】:

我正在尝试将一些简单的控制台日志记录添加到我在 ASP.NET Core 2.2 中的单元测试中,但由于日志记录配置已更改,我遇到了问题。

我目前有这段代码,它为我的班级“DataTests”创建了一个记录器:

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

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

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

但它不会登录到调试窗口,我也无法对其进行配置。我想做类似的事情

factory.AddDebug();

但该扩展程序现已过时且不再可用。它被 ILoggingBuilder 上的扩展取代,而不是 ILoggerFactory。这就是它在文件 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();
}

我的问题是我不知道如何从我的单元测试类中获取 ILoggingBuilder。我怎样才能做到这一点?很遗憾,将一个简单的记录器添加到一个简单的单元测试类中是如此复杂——我认为这应该是默认内置的。

【问题讨论】:

  • 该框架高度模块化,因此您可以自定义您需要的内容,而无需在不需要的地方包含一堆样板膨胀。
  • 您是为了获取日志实例而使用 DI 框架,还是出于其他原因在测试中使用 DI 框架?
  • 我在应用程序中使用 DI,但在单元测试中没有。在单元测试中,我手动注入依赖项。

标签: c# unit-testing logging .net-core


【解决方案1】:

使用AddLogging(IServiceCollection, Action&lt;ILoggingBuilder&gt;) 重载:

var serviceProvider = new ServiceCollection()
    .AddLogging(builder => {
        builder.AddDebug();  //<--

        //...add other logging configuration as needed
    })
    .BuildServiceProvider();

//...

通过配置委托访问构建器。

【讨论】:

  • 谢谢,正是我想要的。但是,现在我想我需要弄清楚如何在没有 appSettings 文件的情况下设置详细程度(因为它是一个单元测试),因为我在调试窗口中看不到任何 EF 日志记录信息。
  • @RandyGamage EF 日志记录?这是单元测试还是集成测试?
  • 这是一个集成测试,因为我实际上是在访问数据库。它实际上是我正在开发的一个研讨会的一部分,向学生展示为各种简单的 EF linq->SQL 生成的实际 SQL,并向他们展示哪些操作将在数据库中运行,哪些将在本地评估等等。所以我想作为研讨会的一部分显示警告和 ef 日志记录。但我只在实际应用程序运行时看到这些日志输出,而不是在 UT 中。
  • 只是为了澄清我也有针对内存中 EF 数据库运行的单元测试,但要求是相同的。在这两种情况下,我都想查看生成的 SQL 的日志。
【解决方案2】:

由于您使用的是 .NET Core,我假设您也在使用 xUnit

xUnit 使用一个特定的接口来记录到控制台,ITestOutputHelper,它由 xUnit 本身在测试夹具构造函数中注入。

有一个 NuGet 包 https://www.nuget.org/packages/Divergic.Logging.Xunit,它可以在 ITextOutputHelper 周围创建一个 ILogger&lt;T&gt; 包装器,以便能够将它们传递给需要 ILogger 接口的系统。

我没有为我的 xUnit 测试使用依赖注入框架,最终我自己用模拟版本将它们连接起来,所以这就是我所做的。

public sealed class MyTestFixture
{
    private readonly ILogger<MyClass> _logger;

    public MyTestFixture(ITestOuputHelper helper)
    {
        _logger = helper.BuildLoggerFor<MyClass>();
    }

    [Fact]
    public void FooBar()
    {
        var myClass = new MyClass(_logger);
        myClass.WizzBang();
    }
}

【讨论】:

  • 我实际上正在使用 mstest,但可能会切换到 xunit。这是非常方便的信息,我将存档,谢谢。
  • 这应该有一个如何使用 XUnits logger 发送日志消息的例子。
  • @FoxDeploy 不太明白你的意思,这个例子展示了如何获取ILogger&lt;T&gt; 实例。
【解决方案3】:

跟进Matthew's answer,根据Capturing Output 中的 xUnit 文档,根据他们网站上的示例将控制台日志记录添加到任何单元测试中很简单:

using Xunit;
using Xunit.Abstractions;

public class MyTestClass
{
    private readonly ITestOutputHelper output;

    public MyTestClass(ITestOutputHelper output)
    {
        this.output = output;
    }

    [Fact]
    public void MyTest()
    {
        var temp = "my class!";
        output.WriteLine("This is output from {0}", temp);
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多