如何在 .NET Core 的 xUnit 测试中使用 NLog? [英] How to use NLog in xUnit tests from .NET Core?
问题描述
我正在尝试通过 NLog 日志库从基于 .NET Core 3.1 的 xUnit 测试用例中输出一些日志消息.在我的主应用程序中,通过 NLog 进行日志记录工作正常,但测试用例不会输出任何消息.
我认为我正在做这个相关问题中建议的所有事情:NLog 在 ASP.NET Core 应用程序中有效,但在 .NET Core xUnit 测试项目中无效>
不知何故,我无法弄清楚缺少什么.我已将代码简化为一个看起来非常简单的最小示例,但仍然没有输出任何内容:
使用NLog;使用 NLog.Config;使用 NLog.Targets;使用系统;使用 Xunit;使用 Xunit.Abstractions;命名空间单元测试{公共类 LoggingTest{公共日志测试(ITestOutputHelper 输出){this.output = 输出;}私有只读 ITestOutputHelper 输出;[事实]公共无效测试日志(){var target = new MemoryTarget {Layout = "${message}"};LogManager.Configuration ??= new LoggingConfiguration();LogManager.Configuration.AddRuleForAllLevels(target);LogManager.GetCurrentClassLogger().Info("Hello, World!");output.WriteLine({0} 行记录:\n{1}", target.Logs.Count, String.Join(\n", target.Logs));}}}
预期输出:
<块引用>记录了 1 行:
你好,世界!
实际输出:
<块引用>记录了 0 行:
作为进一步的跟踪,我在很多地方都读到,如果 appsettings.json 的
文件.我认为这部分也必须添加到我们主应用程序的 Logging
部分中存在某些设置,NLog 只会在 .NET Core 3.1 项目中写入一些内容appsettings.json
文件中.
我不确定如何将这些知识转移到单元测试中,因为它们似乎没有 appsettings.json
文件.我曾尝试将主要的 appsettings.json
文件复制到单元测试的输出目录(我认为,这是从 ReSharper 中运行时的执行目录),但无济于事.
我错过了什么?
要应用配置,您需要assign LogManager.Configuration
,如
LogManager.Configuration = config;
工作示例:
[事实]公共无效测试日志(){var target = new MemoryTarget { Layout = "${message}";};var config = new LoggingConfiguration();config.AddRuleForAllLevels(目标);LogManager.Configuration = config;//<-- 在这里赋值LogManager.GetCurrentClassLogger().Info("Hello, World!");output.WriteLine({0} 行记录:\n{1}", target.Logs.Count, String.Join(\n", target.Logs));Assert.Equal(1, target.Logs.Count);}
奖励:并行测试
奖励,如果您喜欢并行测试(谁不喜欢;)) - 创建一个新的 LogFactory
而不是分配全局 LogManager
.
像这样:
<预><代码>[事实]public void TestLogParallelSafe(){var logFactory = new LogFactory();var target = new MemoryTarget { Layout = "${message}";};var config = new LoggingConfiguration();config.AddRuleForAllLevels(目标);logFactory.Configuration = config;logFactory.GetCurrentClassLogger().Info(Hello, World!");output.WriteLine({0} 行已记录:\n{1}", target.Logs.Count, String.Join(\n", target.Logs));Assert.Equal(1, target.Logs.Count);}当然,如果其他代码正在使用 LogManager
,则您无法断言这些日志.
.NET Core 集成
<块引用>作为进一步的跟踪,我在很多地方都读到过,如果 appsettings.json 文件的 Logging 部分中存在某些设置,NLog 只会在 .NET Core 3.1 项目中写入一些内容.我认为这部分也必须添加到我们主应用程序的 appsettings.json 文件中.
这仅在与 ASP.NET Core 集成时才需要 - 例如当注入来自 Microsoft 的 ILogger
时.这里不需要.如需进一步参考,请参阅 ASP 入门.NET Core 3 · NLog/NLog 维基
I am trying to output some log messages from within .NET Core 3.1-based xUnit test cases by means of the NLog logging library. Logging by means of NLog works fine in my main application, but the test cases just won't output any messages.
I think I am doing everything suggested in this related question: NLog works in ASP.NET Core App but not in .NET Core xUnit Test Project
Somehow, though, I cannot figure out what is missing. I have reduced my code into a minimal sample that seems very straightforward, but still does not output anything:
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));
}
}
}
Expected output:
1 line(s) logged:
Hello, World!
Actual output:
0 line(s) logged:
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.
I am not sure how to transfer this knowledge to the unit tests, though, as they do not appear to come with an appsettings.json
file. I have tried copying the main appsettings.json
file to the output directory of the unit tests (which is, I think, their execution directory when run from within ReSharper), but to no avail.
What am I missing?
To apply the config, you need to assign LogManager.Configuration
, like
LogManager.Configuration = config;
Working example:
[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);
}
Bonus: tests in parallel
Bonus, if you like tests in parallel (who doesn't ;)) - create a new LogFactory
instead of assigning the global LogManager
.
Like this:
[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);
}
Of course if other code is using the LogManager
, you can't assert those logs.
.NET Core integration
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.
This is only needed when integrating with ASP.NET Core - e.g. when injection the ILogger<T>
from Microsoft. That's is not needed here. For further reference, see Getting started with ASP.NET Core 3 · NLog/NLog Wiki
这篇关于如何在 .NET Core 的 xUnit 测试中使用 NLog?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!