Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/295.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# NET核心应用程序中单元测试的模拟日志文件_C#_Asp.net_Unit Testing_.net Core_Nlog - Fatal编程技术网

C# NET核心应用程序中单元测试的模拟日志文件

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

在我的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
变量的代码进行单元测试。我想以某种方式模拟一下,因为我想在测试中使用特定的日志数据,但不确定如何进行。如何做到这一点?

模拟
私有静态
字段或方法实际上是不可能的。 作为另一个类的私有成员使用这种方法闻起来像是违反了单一责任原则

您可能应该将此行为重构为单独的类,并将其隐藏在接口后面。我不完全确定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包提供:。