NLog和单元测试

The*_*oob 2 c# unit-testing nlog visual-studio

我正在使用NLog作为记录器。当我运行.exe,甚至通过Visual Studio进行调试时,登录时一切正常,NLog仍会写入该文件。

但是,如果我运行一个通过单元测试调用记录器的对象,则会创建该文件,但该文件为空。我是否需要添加到配置中以使NLog在单元测试下写入文件,需要额外的设置/规则?

我可以为此模拟NLog并且没有日志转储,但是我想看看是否可以在决定模拟NLog之前使其工作。即使这仅在单元测试中发生并且在其他情况下仍然有效,这还是我的配置和日志记录代码。我忽略了文件名。

public static void Info(string app, string m)  => EngineLogger.Logger.Info($"{app} : {m}");



<targets>
    <target name="infoFile"
            xsi:type="File"
            layout="${date:format=yyyy-MM-dd HH\:mm\:ss} ${pad:padding=5:inner=${level:uppercase=true}} ${logger} ${message}"
            fileName="leftoutForQuestion"
            keepFileOpen="false"
            encoding="iso-8859-2" />
    <target name="errorFile"
            xsi:type="File"
            layout="${date:format=yyyy-MM-dd HH\:mm\:ss} ${pad:padding=5:inner=${level:uppercase=true}} ${logger} ${message}"
            fileName="leftOutForQuestion"
            keepFileOpen="false"
            encoding="iso-8859-2" />
  </targets>
  <rules>
    <logger name="*" minlevel="Debug" maxlevel="Info" writeTo="infoFile" />
    <logger name="*" minlevel="Warn" maxlevel="Fatal" writeTo="errorFile" />
  </rules>
Run Code Online (Sandbox Code Playgroud)

这是内部日志中的错误:

Error Error has been raised. Exception: System.Runtime.InteropServices.COMException (0x800700A1): The specified path is invalid. (Exception from HRESULT: 0x800700A1)
   at System.Runtime.InteropServices.Marshal.ThrowExceptionForHRInternal(Int32 errorCode, IntPtr errorInfo)
   at NLog.Internal.FileAppenders.BaseFileAppender.WindowsCreateFile(String fileName, Boolean allowFileSharedWriting)
   at NLog.Internal.FileAppenders.BaseFileAppender.TryCreateFileStream(Boolean allowFileSharedWriting)
   at NLog.Internal.FileAppenders.BaseFileAppender.CreateFileStream(Boolean allowFileSharedWriting)
   at NLog.Internal.FileAppenders.RetryingMultiProcessFileAppender.Write(Byte[] bytes)
   at NLog.Targets.FileTarget.WriteToFile(String fileName, LogEventInfo logEvent, Byte[] bytes, Boolean justData)
   at NLog.Targets.FileTarget.ProcessLogEvent(LogEventInfo logEvent, String fileName, Byte[] bytesToWrite)
   at NLog.Targets.FileTarget.Write(LogEventInfo logEvent)
   at NLog.Targets.Target.Write(AsyncLogEventInfo logEvent)
Run Code Online (Sandbox Code Playgroud)

小智 6

我发现所有配置都驻留在单元测试项目的app.config中,而不是NLog.Config文件。确保先声明config部分,然后先声明NLog配置。以下是我的示例app.config

    <configuration>
      <configSections>

         <section name="nlog"
                    type="NLog.Config.ConfigSectionHandler, NLog"/>
  </configSections>
  <nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

    <targets>


      <target name="file" xsi:type="File"
             layout="${longdate} ${logger} ${message}"
             fileName="${basedir}/logs/${shortdate}.log" />

    </targets>
   <rules>
       <logger name="*" minlevel="Trace" writeTo="file"/>

    </rules>

  </nlog>
</configuration>
Run Code Online (Sandbox Code Playgroud)


Rol*_*sen 5

当并行执行单元测试时,最好为每个并行执行使用隔离的 NLog LogFactory:

LogFactory logFactory = new LogFactory();
logFactory.Configuration = new XmlLoggingConfiguration(configFilePath, true, logFactory); 
Logger logger = logFactory.GetCurrentClassLogger();
Run Code Online (Sandbox Code Playgroud)

另请参阅https://github.com/NLog/NLog/wiki/Configure-component-logging

如果您需要从字符串而不是文件加载 NLog 配置:

string currentDir = System.IO.Directory.GetCurrentDirectory();
System.IO.StringReader sr = new System.IO.StringReader(xmlString);
System.Xml.XmlReader xr = System.Xml.XmlReader.Create(sr);
logFactory.Configuration.Configuration = new NLog.Config.XmlLoggingConfiguration(xr, currentDir);
Run Code Online (Sandbox Code Playgroud)

另请参阅https://github.com/NLog/NLog/wiki/Explicit-NLog-configuration-loading


Jul*_*ian 2

不确定这是否是问题所在,但很确定是:

从单元测试环境中读取 NLog.config 可能很困难,因此从单元测试中的字符串中读取配置更为稳健。我们使用助手:

    protected XmlLoggingConfiguration CreateConfigurationFromString(string configXml)
    {
        XmlDocument doc = new XmlDocument();
        doc.LoadXml(configXml);

        return new XmlLoggingConfiguration(doc.DocumentElement, Environment.CurrentDirectory);
    }
Run Code Online (Sandbox Code Playgroud)

进而:

 LogManager.Configuration = CreateConfigurationFromString(@"
            <nlog throwExceptions='true'>
                <targets><target name='debug' type='debug' layout='${message}' /></targets>
                <rules>
                    <logger name='*' minlevel='info' appendto='debug'>
                        <filters>
                            <whencontains layout='${message}' substring='msg' action='ignore' />
                        </filters>
                    </logger>
                </rules>
            </nlog>");
Run Code Online (Sandbox Code Playgroud)

LogManager.Configuration不要忘记在每次测试之前或之后重置。

更新:在配置中启用 throwExceptions。

还有关于错误。您可能需要单元测试中的绝对路径。