【发布时间】:2022-03-03 23:13:32
【问题描述】:
使用 Rhino Mocks 或类似方法模拟 NLog 日志方法是否可能/容易?
【问题讨论】:
-
查看详细帖子Using NLog with Dependency Injection。该帖子使用 NInject 作为 DI 示例。
标签: nlog
使用 Rhino Mocks 或类似方法模拟 NLog 日志方法是否可能/容易?
【问题讨论】:
标签: nlog
使用 Nuget:install-package NLog.Interface
然后:ILogger logger = new LoggerAdapter([logger-from-NLog]);
【讨论】:
您只能模拟虚拟方法。但是,如果您创建一些用于日志记录的接口,然后使用 NLog 实现它,您可以使用依赖注入并在您的测试中使用模拟接口来查看被测系统 (SUT) 是否正在记录您期望它记录的内容。
public class SUT
{
private readonly ILogger logger;
SUT(ILogger logger) { this.logger = logger;}
MethodUnderTest() {
// ...
logger.LogSomething();
// ...
}
}
// and in tests
var mockLogger = new MockLogger();
var sut = new SUT(mockLogger);
sut.MethodUnderTest();
Assert.That("Expected log message", Is.Equal.To(mockLogger.LastLoggedMessage));
【讨论】:
简单的答案是“不”。查看代码,不支持依赖注入,这似乎是一种疏忽,尤其是因为它看起来并不难实现(乍一看)。
项目中唯一的接口用于支持 COM 互操作对象和其他一些东西。主要的Logger 具体类既不实现接口,也不提供虚方法。
你可以自己提供一个接口,或者使用 Moles/TypeMock/ 另一个隔离框架来模拟依赖。
【讨论】:
我已经使用这样的代码来存根 NLog 日志记录代码。您可以使用 NLog 的 MemoryTarget,它只是将消息保存在内存中,直到它被处理掉。您可以使用 Linq 或其他方式查询日志的内容(本示例使用 FluentAssertions)
using FluentAssertions
using Microsoft.VisualStudio.TestTools.UnitTesting;
using NLog;
using NLog.Config;
using NLog.Targets;
...
private MemoryTarget _stubLogger;
[TestInitialize]
public void Setup()
{
ConfigureTestLogging();
}
protected virtual LoggingConfiguration GetLoggingConfiguration()
{
var config = new NLog.Config.LoggingConfiguration();
this._stubLogger = new MemoryTarget();
_stubLogger.Layout = "${level}|${message}";
config.AddRule(LogLevel.Debug, LogLevel.Fatal, this._stubLogger);
return config;
}
protected virtual void ConfigureTestLogging()
{
var config = GetLoggingConfiguration();
NLog.LogManager.Configuration = config;
}
[TestMethod]
public void ApiCallErrors_ShouldNotThrow()
{
// arrange
var target = new Thing();
// act
target.DoThing();
// assert
this._stubLogger.Logs.Should().Contain(l =>
l.Contains("Error|") &&
l.Contains("Expected Message"));
}
【讨论】: