C# NET核心应用程序中单元测试的模拟日志文件
在我的C#应用程序中,我有一个C# NET核心应用程序中单元测试的模拟日志文件,c#,asp.net,unit-testing,.net-core,nlog,C#,Asp.net,Unit Testing,.net Core,Nlog,在我的C#应用程序中,我有一个getLogFile,它是通过调用getLogFile()方法设置的: private static string getLogFile = GetLogFile(); private static string GetLogFile() { var fileTarget = (FileTarget)LogManager.Configuration.FindTargetByName("file-target"); var log
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
变量的代码进行单元测试。我想以某种方式模拟一下,因为我想在测试中使用特定的日志数据,但不确定如何进行。如何做到这一点?模拟私有静态
字段或方法实际上是不可能的。
作为另一个类的私有成员使用这种方法闻起来像是违反了单一责任原则
您可能应该将此行为重构为单独的类,并将其隐藏在接口后面。我不完全确定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;
}
}
以和为例进行测试:
[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
}
[理论]
public void TestWithMockedLogFileName()
{
//安排
var mocker=new AutoMocker();
var logFileNameProviderMock=mocker.GetMock();
logFileNameProviderMock.Setup(x=>x.GetLogFileName()).Returns(“您的模拟文件名.log”);
var sut=mocker.CreateInstance();
//表演
var result=sut.TestedMethodWhichUsesLogFileName();
//断言您想要测试的任何内容
}
这还允许您交换当前逻辑,以便稍后获得日志文件,而无需更改现有类的逻辑。使用.NET Core的日志记录(或任何其他日志记录库,如Serilog、NLog),而不是尝试模拟私有字段或者模拟
ILogger
接口,或者添加测试接收器,而不是实际的sinksBTW。无论如何,您都必须使用ILogger
——所有需要日志记录的.NET核心包都希望这样做。这是否回答了您的问题?谢谢@bloodymetle。什么是AutoMocker()
?@runnerpaul-AutoMocker是Moq框架的扩展,它简化了模拟设置:。它也可以作为nuget包提供:。