如何在 .NET Core 的 xUnit 测试中使用 NLog?
How to use NLog in xUnit tests from .NET Core?
我正在尝试通过 NLog 日志库从基于 .NET Core 3.1 的 xUnit 测试用例中输出一些日志消息。通过 NLog 进行日志记录在我的主应用程序中工作正常,但测试用例不会输出任何消息。
我认为我正在做这个相关问题中建议的一切:
但是,不知何故,我无法弄清楚缺少什么。我已将我的代码缩减为一个看起来非常简单的最小示例,但仍然不输出任何内容:
using NLog;
using NLog.Config;
using NLog.Targets;
using System;
using Xunit;
using Xunit.Abstractions;
namespace UnitTests
{
public class LoggingTest
{
public LoggingTest(ITestOutputHelper output)
{
this.output = output;
}
private readonly ITestOutputHelper output;
[Fact]
public void TestLog()
{
var target = new MemoryTarget {Layout = "${message}"};
LogManager.Configuration ??= new LoggingConfiguration();
LogManager.Configuration.AddRuleForAllLevels(target);
LogManager.GetCurrentClassLogger().Info("Hello, World!");
output.WriteLine("{0} line(s) logged:\n{1}", target.Logs.Count, String.Join("\n", target.Logs));
}
}
}
预期输出:
1 line(s) logged:
Hello, World!
实际输出:
0 line(s) logged:
作为进一步的跟踪,我在各个地方读到,如果 appsettings.json
文件的 Logging
部分中存在某些设置,NLog 只会在 .NET Core 3.1 项目中写入内容。我认为这部分也必须添加到我们的主应用程序的 appsettings.json
文件中。
不过,我不确定如何将这些知识转移到单元测试中,因为它们似乎没有随 appsettings.json
文件一起提供。我尝试将主 appsettings.json
文件复制到单元测试的输出目录(我认为,当 运行 来自 ReSharper 时,它们的执行目录),但无济于事。
我错过了什么?
要应用配置,您需要分配 LogManager.Configuration
,喜欢
LogManager.Configuration = config;
工作示例:
[Fact]
public void TestLog()
{
var target = new MemoryTarget { Layout = "${message}" };
var config = new LoggingConfiguration();
config.AddRuleForAllLevels(target);
LogManager.Configuration = config; // <-- assign here
LogManager.GetCurrentClassLogger().Info("Hello, World!");
output.WriteLine("{0} line(s) logged:\n{1}", target.Logs.Count, String.Join("\n", target.Logs));
Assert.Equal(1, target.Logs.Count);
}
奖励:并行测试
奖金,如果你喜欢并行测试(谁不喜欢 ;)) - 创建一个新的 LogFactory
而不是分配全局 LogManager
.
像这样:
[Fact]
public void TestLogParallelSafe()
{
var logFactory = new LogFactory();
var target = new MemoryTarget { Layout = "${message}" };
var config = new LoggingConfiguration();
config.AddRuleForAllLevels(target);
logFactory.Configuration = config;
logFactory.GetCurrentClassLogger().Info("Hello, World!");
output.WriteLine("{0} line(s) logged:\n{1}", target.Logs.Count, String.Join("\n", target.Logs));
Assert.Equal(1, target.Logs.Count);
}
当然,如果其他代码正在使用 LogManager
,您将无法断言这些日志。
.NET 核心集成
As one further trace, I have read in various places that NLog will only write something in .NET Core 3.1 projects if certain settings are present in a Logging section of the appsettings.json file. I think this section also had to be added to our main application's appsettings.json file.
这仅在与 ASP.NET 核心集成时才需要 - 例如注入 Microsoft 的 ILogger<T>
时。这里不需要。如需进一步参考,请参阅 Getting started with ASP.NET Core 3 · NLog/NLog Wiki
我正在尝试通过 NLog 日志库从基于 .NET Core 3.1 的 xUnit 测试用例中输出一些日志消息。通过 NLog 进行日志记录在我的主应用程序中工作正常,但测试用例不会输出任何消息。
我认为我正在做这个相关问题中建议的一切:
但是,不知何故,我无法弄清楚缺少什么。我已将我的代码缩减为一个看起来非常简单的最小示例,但仍然不输出任何内容:
using NLog;
using NLog.Config;
using NLog.Targets;
using System;
using Xunit;
using Xunit.Abstractions;
namespace UnitTests
{
public class LoggingTest
{
public LoggingTest(ITestOutputHelper output)
{
this.output = output;
}
private readonly ITestOutputHelper output;
[Fact]
public void TestLog()
{
var target = new MemoryTarget {Layout = "${message}"};
LogManager.Configuration ??= new LoggingConfiguration();
LogManager.Configuration.AddRuleForAllLevels(target);
LogManager.GetCurrentClassLogger().Info("Hello, World!");
output.WriteLine("{0} line(s) logged:\n{1}", target.Logs.Count, String.Join("\n", target.Logs));
}
}
}
预期输出:
1 line(s) logged:
Hello, World!
实际输出:
0 line(s) logged:
作为进一步的跟踪,我在各个地方读到,如果 appsettings.json
文件的 Logging
部分中存在某些设置,NLog 只会在 .NET Core 3.1 项目中写入内容。我认为这部分也必须添加到我们的主应用程序的 appsettings.json
文件中。
不过,我不确定如何将这些知识转移到单元测试中,因为它们似乎没有随 appsettings.json
文件一起提供。我尝试将主 appsettings.json
文件复制到单元测试的输出目录(我认为,当 运行 来自 ReSharper 时,它们的执行目录),但无济于事。
我错过了什么?
要应用配置,您需要分配 LogManager.Configuration
,喜欢
LogManager.Configuration = config;
工作示例:
[Fact]
public void TestLog()
{
var target = new MemoryTarget { Layout = "${message}" };
var config = new LoggingConfiguration();
config.AddRuleForAllLevels(target);
LogManager.Configuration = config; // <-- assign here
LogManager.GetCurrentClassLogger().Info("Hello, World!");
output.WriteLine("{0} line(s) logged:\n{1}", target.Logs.Count, String.Join("\n", target.Logs));
Assert.Equal(1, target.Logs.Count);
}
奖励:并行测试
奖金,如果你喜欢并行测试(谁不喜欢 ;)) - 创建一个新的 LogFactory
而不是分配全局 LogManager
.
像这样:
[Fact]
public void TestLogParallelSafe()
{
var logFactory = new LogFactory();
var target = new MemoryTarget { Layout = "${message}" };
var config = new LoggingConfiguration();
config.AddRuleForAllLevels(target);
logFactory.Configuration = config;
logFactory.GetCurrentClassLogger().Info("Hello, World!");
output.WriteLine("{0} line(s) logged:\n{1}", target.Logs.Count, String.Join("\n", target.Logs));
Assert.Equal(1, target.Logs.Count);
}
当然,如果其他代码正在使用 LogManager
,您将无法断言这些日志。
.NET 核心集成
As one further trace, I have read in various places that NLog will only write something in .NET Core 3.1 projects if certain settings are present in a Logging section of the appsettings.json file. I think this section also had to be added to our main application's appsettings.json file.
这仅在与 ASP.NET 核心集成时才需要 - 例如注入 Microsoft 的 ILogger<T>
时。这里不需要。如需进一步参考,请参阅 Getting started with ASP.NET Core 3 · NLog/NLog Wiki