c# - .NET Core 应用程序中单元测试的模拟日志文件
问题描述
在我的 C# 应用程序中,我有一个getLogFile
通过调用GetLogFile()
方法设置的:
private static string getLogFile = GetLogFile();
private static string GetLogFile()
{
var fileTarget = (FileTarget)LogManager.Configuration.FindTargetByName("file-target");
var logEventInfo = new LogEventInfo();
string fileName = fileTarget.FileName.Render(logEventInfo);
if (!File.Exists(fileName))
throw new Exception("Log file does not exist.");
return fileName;
}
我现在正在尝试对一些需要设置getLogFile
变量的代码进行单元测试。我想以某种方式模拟它,因为我想使用特定的日志数据进行测试,但不知道如何去做。我怎样才能做到这一点?
解决方案
“模拟”一个private static
领域或方法是不可能的。将这种方法作为另一个类的私有成员,这听起来像是违反了单一责任原则。
您可能应该将此行为重构为一个单独的类并将其隐藏在接口后面。我不完全确定 NLog 代码的作用,但您的方法似乎真正做的不是提供日志文件,而是提供日志文件的名称(您返回fileName
)所以这就是它的样子:
public interface ILogFileNameProvider
{
string GetLogFileName();
}
public class DefaultLogFileNameProvider : ILogFileNameProvider
{
public string GetLogFileName()
{
// your code ommitted
}
}
这只是一个关于如何处理它的例子。命名/结构以及如何使用它取决于您。然后可以将该接口注入到当前具有私有方法的 using 类中。可以模拟此依赖项/调用。
构造函数注入的用法:
public class LogFileNameUsingService
{
private readonly ILogFileNameProvider _logFileNameProvider;
public LogFileNameUsingService(ILogFileNameProvider logFileNameProvider)
{
_logFileNameProvider = logFileNameProvider;
}
}
以xUnit和AutoMocker为例进行测试:
[Theory]
public void TestWithMockedLogFileName()
{
//Arrange
var mocker = new AutoMocker();
var logFileNameProviderMock = mocker.GetMock<ILogFileNameProvider>();
logFileNameProviderMock.Setup(x => x.GetLogFileName()).Returns("your mocked file name.log");
var sut = mocker.CreateInstance<LogFileNameUsingService>();
//Act
var result = sut.TestedMethodWhichUsesLogFileName();
//Assert whatever you want to test
}
这也允许您交换当前逻辑以稍后获取日志文件,而无需更改现有类的逻辑。
推荐阅读
- html - Spring Boot 应用程序 - thymeleaf 会在一段时间后加载图片。某种缓存问题?
- azure - Azure DevOps Pipeline Build Immutable Image (Packer) 找不到脚本
- memory-leaks - 通知程序的潜在内存泄漏
- docker - Docker NGINX sub_filter 在响应中不适用于 HTML-form-item “action”
- node.js - agent.add 不工作,而 console.log 是
- c# - ObserwableCollection 中的 SearchBar 和 List MVVM
- windows - 在 LotusScript 中确定 Windows 剪贴板的内容
- flutter - 如何在等待函数中添加超时
- java - 在 Java 方法中创建对象
- angular - 错误:NullInjectorError:路由器没有提供程序