Assembly.GetEntryAssembly().代码库排除了单元测试

本文关键字:排除 单元测试 代码 GetEntryAssembly Assembly | 更新日期: 2023-09-27 18:35:05

可能的重复项:
.NET NUnit test - Assembly.GetEntryAssembly() is null

我正在编写一个日志记录库。默认情况下,我希望库写入以应用程序命名的公共应用程序数据文件夹中的目录。例如,如果应用程序名为"MyApplication.exe",我希望将数据保存在"C:''ProgramData''MyApplication"中。

我正在使用以下代码来构造路径:

   private static string loggingDataPath = 
      Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData) +
      Path.DirectorySeparatorChar + 
      Path.GetFileNameWithoutExtension(Assembly.GetEntryAssembly().CodeBase) +
      Path.DirectorySeparatorChar;

这完全符合预期,但有一个问题。我无法对库进行单元测试!

当我尝试运行单元测试时,它们都失败了,并显示System.NullReferenceException。如果我替换"Assembly.GetEntryAssembly()。代码库"调用与字符串单元测试再次正常运行。

我想我明白为什么会发生这种情况,但我不知道如何解决这个问题。我希望有人能让我走上正义的道路。

啪!

更新(5-24-12):我不是在尝试对"loggingDataPath"的内容进行单元测试。仅仅是"Assembly.GetEntryAssembly()"的存在。代码库"调用会导致所有单元测试失败,并出现上述异常。请注意,"loggingDataPath"是静态的(因为它必须是静态库)。

Assembly.GetEntryAssembly().代码库排除了单元测试

不仅仅是

单元测试会导致问题。

鉴于 GetEntryAssembly() 可以在从非托管应用程序加载托管程序集时返回 null,并且 CodeBase 可以包含从 Internet 下载的程序集的 URL,并且未为从 GAC 加载的程序集设置,因此我将避免为通用日志记录库尝试此方法。

如果这还不足以说服您,其他问题是 (a) 非特权用户对 CommonApplicationData 没有写入权限,以及 (b) 尝试写入同一日志文件的应用程序的多个实例将是一个问题。

相反,我将在配置中定义日志文件的位置。

你会建议我把它放在哪里以避免这个问题?

正如我所说,我会在配置中定义它(例如,app.config 中的 appSet)。 这是最灵活的。 如果要将其放在 CommonApplicationData 下,则可以使用在读取配置文件时使用 Environment.ExpandEnvironmentVariables 方法扩展的环境变量。 例如:

<appSettings>
    <add key="logFile" value="%ALLUSERSPROFILE%'MyApp'MyLogFile.log" />
    ...
</appSettings>

您仍然需要解决向非特权用户授予访问权限的问题,并避免从多个实例访问时发生争用。 您说基础日志记录库支持并发访问,但请注意,这将产生潜在的性能成本,具体取决于日志记录的详细程度。

忽略先前答案的明智建议,只解决我的问题,这是我解决问题的方法:

   public static string LoggingDataPath { 
      get { 
         return loggingDataPath.Length > 0 ? loggingDataPath : 
         Environment.GetFolderPath(Environment.SpecialFolder.CommonDocuments) + 
         Path.DirectorySeparatorChar + 
         Path.GetFileNameWithoutExtension(Assembly.GetEntryAssembly().CodeBase) + 
         Path.DirectorySeparatorChar; 
      } 
      set { loggingDataPath = value; } 
   } 

此解决方案避免在第一次访问静态类时初始化"loggingDataPath",从而避免调用"Assembly.GetEntryAssembly()。代码库'。