5

在我的程序中,我使用 SevenZipSharp 生成 zip 文件。SevenZipSharp 是一个托管 DLL,它加载另一个 DLL,7z.dll。我正在使用 SevenZipCompressor.SetLibraryPath 手动设置 SevenZipSharp 到 7z.dll 的路径。

当我在调试模式下执行我的程序时,一切正常,它会生成你喜欢的 zip 文件。但是,当我使用 mstest 执行单元测试时,SevenZipSharp 总是给我以下错误:

测试方法抛出异常:SevenZip.SevenZipLibraryException:无法加载 7-zip 库或内部 COM 错误!消息:加载库失败..

我怀疑 MSTest 可能正在做一些阻止 SevenZipSharp 能够加载 7z.dll 的事情,比如在安全严格的沙箱中运行(或其他东西。我是 C# 和 MSTest 的新手......)

有谁知道可能发生的事情?

谢谢!

4

4 回答 4

5

虽然这个问题提出了一个有问题的场景,但 MSTest 不加载所需 DLL 的一般问题似乎是一个常见问题,值得一个不那么轻视的答案。

  1. 默认情况下,MSTest 会将它认为测试容器所需的程序集复制到默认结果文件夹的 Out 文件夹,每次运行都会更改。

  2. MSTest 并不总是自动正确地推断出必要的程序集;如果没有对程序集的显式直接引用,则不会复制它。此外,通常不会检测到本机 DLL。

  3. 我不知道设置 MSTest 搜索路径的直接选项。您可以按照上面的建议使用 procmon.exe 确定搜索路径(它基本上是标准的 Windows DLL 搜索)。

  4. 不直观的是,默认搜索路径不包括启动目录,我认为这是造成混淆的原因。运行测试时,当前目录是测试结果“Out”目录,而不是 MSTest 启动目录。

但是,可以使用测试设置文件来控制 MSTest 搜索行为(和复制行为)。您可以通过 Visual Studio 轻松创建和编辑这些(请参阅测试菜单),然后在 MSTest 命令行上指定创建的设置文件。您可以为 Visual Studio 和 MSTest 使用不同的设置文件。

通过这种方式,您可以准确控制将哪些 DLL 复制到您的测试目录。请参阅创建测试设置以从 Visual Studio 运行自动化测试以获取更多信息。

当然,DLL 加载失败可能是由于缺少依赖关系,错误消息中提到的 DLL本身可能存在。您可以使用依赖项查看器或 procmon 来获取 DLL 中的意外依赖项。

于 2014-08-29T01:25:43.927 回答
2

考虑使用Process Monitor (aka procmon.exe)优秀的SysInternals 工具来监控您的测试工具 (MSTest)。它会告诉你可执行文件在哪里寻找 7z.dll。

于 2011-08-30T22:03:10.473 回答
2

Visual Studio 2017(可能还有 2015)提供了两种新方法来指示测试需要本机 dll 或其他文件,而无需测试设置文件:

1:将dll链接添加到您的测试项目中,并告诉VS将其复制到输出目录。右键单击解决方案资源管理器中的项目,然后选择添加 > 现有项。浏览到 7z.dll,单击“添加”按钮旁边的向下箭头,然后选择“添加为链接”。然后在解决方案资源管理器中选择新的 7z.dll 项,alt-Enter 调出属性,并将“复制到输出目录”设置为“如果较新则复制”(或“始终复制”)。

2:附加DeploymentItemAttribute到你的测试类。此属性的构造函数采用单个字符串参数,它是您希望在类中的测试可用的文件的路径。它相对于测试项目的输出目录。

于 2018-01-23T15:20:47.477 回答
0

您确定要让您的单元测试涉及外部库吗?理想情况下,您应该拥有用模拟对象替换外部内容的机制,因为像这样测试外部库实际上会将您的测试变成集成测试。

对于诸如 SevenZipSharp 之类的流行库,您可以假设它已经过正确测试,并且您可以进行手动集成测试以验证它在您的程序中是否正确执行。

我会考虑通过依赖注入、模拟框架等来摆脱这种依赖,让你的单元测试只测试你自己的代码。

研究工厂方法或抽象工厂设计模式以获取有关如何轻松替换此类依赖项的提示。

一个好的开始是创建自己的 ICustomZipInterface,并使用包装器模式来封装生产代码的 zip 逻辑。在您的单元测试中,将该包装类替换为虚拟实现。例如,虚拟实现可能会记录您如何访问 zip 组件,并且您可以使用该信息来验证您的代码,而不是检查是否实际创建了 zip 文件。

于 2011-08-30T22:10:37.293 回答