【问题标题】:Including resources file for Unit test in C# project在 C# 项目中包含单元测试的资源文件
【发布时间】:2010-07-20 12:02:06
【问题描述】:

我有一些读取和修改文件的函数。为了使单元测试独立于任何文件系统问题,我想将文件包含在项目中。

但是,我的函数应该是获取文件路径,而我能从程序集中得到的只是一个 FileStream。知道如何获取项目中资源文件的文件路径吗?

System.Reflection.Assembly a = System.Reflection.Assembly.Load(assemblyName);
FileStream stream = a.GetFile(assemblyName + "." + fileName);

【问题讨论】:

  • 恕我直言,此类测试数据永远不应内置到测试中,而应单独提供(这也使您可以使用不同的数据重新运行测试而无需重建)。您担心哪种文件系统问题?
  • 我不喜欢单元测试依赖于可以更改、移动、更改等的外部资源。这个单元测试是为了检查 1 个场景,我想要测试那个确切的场景,所以它应该独立于文件权限可以更改、打开的文件处理程序太多、NTFS 磁盘不可用等事实。 .
  • 我认为这是一个非常好的问题。至于真正的单元测试,我承认应该避免使用文件数据,但是如果您想到集成测试(例如,我目前正在编写文件阅读器),那么使用“真实”测试数据是有意义的。

标签: c# unit-testing assemblies


【解决方案1】:

对于这个问题,我通常的解决方案是重构我的程序,在调用方法中打开文件,然后传递一个 Stream,而不是传递文件名并在那里打开文件。

对于测试,这允许我传递一个 MemoryStream,这样我就可以在不使用文件系统的情况下编写我的单元测试。有时检查数据是否正确写入更容易,而且速度肯定更快,尤其是对于更多数量的测试。您只需要记住在写入后刷新 MemoryStream,因为 .NET 并不总是自动执行此操作。

来自我的一个程序的示例:

public TestSaveAndLoad()
{
  [... create data to save ...]
  using (MemoryStream targetStream = new MemoryStream())
  {
    target.Save(targetStream);
    targetStream.Flush();
    targetStream.Seek(0, ...);
    target.Load(targetStream);
  }
  [... assert that the loaded data equals the saved data ...]
}

【讨论】:

  • 酷。我不喜欢那些到处乱跑的流,这看起来是个不错的解决方案。
【解决方案2】:

文件系统上不存在嵌入式资源,因此它没有任何文件路径。

你有两个选择:

  • 更改 SUT 的 API,使其接受 Stream 而不仅仅是文件路径。此解决方案非常受欢迎
  • 在单元测试期间将嵌入的资源保存到一个临时文件中,确保在每个测试用例之后再次将其删除。

第一个解决方案是 TDD 如何推动我们实现更好、更灵活的 API 的绝佳示例。

【讨论】:

  • 我从 Stream 开始,但我觉得我在处理许多开放的处理程序。不过,我会再考虑一下。谢谢。
  • 您始终可以创建重载方法:一个采用文件路径,但实际上只是委托给另一个采用 Stream...
【解决方案3】:

您可以在项目构建时设置要复制到 bin 目录的数据文件,然后在您的测试中通过Directory.GetCurrentDirectory() 引用它们。或者甚至将它们留在原处并简单地使用基于当前目录的相对路径。

不过,更好的办法是重构您的代码以依赖 Stream 类,然后结合使用模拟和依赖注入来为模拟流提供数据——或者如果伪造效果更好,则使用内存流。

【讨论】:

  • 一些测试运行器在运行测试时没有将 bin 目录作为当前目录。使用AppDomain.CurrentDomain.BaseDirectory获取部署目录,而不是Directory.GetCurrentDirectory()
【解决方案4】:

如果您将文件的构建操作设置为复制,那么您可以预测文件应该在哪里(可能是一堆 .. \ .. \ .. \ ,但仍然如此)。我猜你对文件名的方法有一个输入,所以应该可以正常工作。

作为一个建议,是否可以将该文件的实际读取/更改抽象为一个方法并传递一个字符串值?我提出这个问题的唯一原因是它闻起来像集成测试(涉及文件系统)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-05
    • 1970-01-01
    • 2018-10-02
    • 2010-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多