在我的程序中,我使用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的新手......)
有没有人知道可能会发生什么?
谢谢!
答案 0 :(得分:4)
虽然这个问题提出了一个值得怀疑的问题,但MSTest没有加载所需DLL的一般问题似乎是一个常见问题,值得一个不那么轻率的答案。
默认情况下,MSTest会将其认为测试容器所需的程序集复制到默认结果文件夹的Out文件夹中,该文件夹会针对每次运行进行更改。
MSTest并不总是自动正确地推断出必要的装配;如果没有明确的直接引用汇编,则不会被复制。此外,通常不会检测到本机DLL。
我不知道设置MSTest搜索路径的直接选项。您可以使用procmon.exe确定搜索路径,如上所述(它基本上是标准的Windows DLL搜索)。
非直观地,默认搜索路径不包含启动目录,我认为这是造成混淆的原因。当测试运行时,当前目录是测试结果" Out"目录,而不是MSTest启动目录。
但是, 可以使用测试设置文件控制MSTest搜索行为(以及复制行为)。您可以通过Visual Studio轻松创建和编辑这些内容(请参阅“测试”菜单),然后在MSTest命令行上指定创建的设置文件。您可以为Visual Studio和MSTest使用不同的设置文件。
通过这种方式,您可以准确控制将哪些DLL复制到测试目录中。 请参阅Create Test Settings to Run Automated Tests from Visual Studio以获取有关此内容的更多信息。
当然,DLL加载失败可能是由于缺少依赖性,并且错误消息中提到的DLL可能本身存在。您可以使用依赖项查看器或procmon来获取DLL中的意外依赖项。
答案 1 :(得分:2)
考虑使用优秀SysInternals tools中的Process Monitor (aka procmon.exe)
来监控您的测试工具(MSTest)。它将显示可执行文件在哪里查找7z.dll。
答案 2 :(得分:1)
您确定要让您的单元测试涉及外部库吗?理想情况下,你应该有机制来替换外部的东西,例如模拟对象,因为像这样测试外部库实际上会将您的测试变成集成测试。
对于流行的库,例如SevenZipSharp,您可以假设它已经过适当的测试,您可以通过手动集成测试来验证它是否在您的程序中正确执行。
我会考虑通过依赖注入,模拟框架等来摆脱这种依赖,让你的单元测试只测试你自己的代码。
调查工厂方法或抽象工厂设计模式,以获取有关如何轻松替换此类依赖项的提示。
一个好的开始是创建自己的ICustomZipInterface,并使用包装器模式封装生产代码的zip逻辑。在单元测试中,用虚拟实现替换该包装类。例如,虚拟实现可以记录您访问zip组件的方式,并且可以使用该信息来验证代码,而不是检查是否实际创建了zip文件。
答案 3 :(得分:1)
Visual Studio 2017(可能还有2015)提供了两种新方法来指示测试需要本机dll或其他文件,而无需测试设置文件:
1:向测试项目添加指向dll的链接,并告诉VS将其复制到输出目录。在解决方案资源管理器中右键单击该项目,然后选择添加>现有项目。浏览到7z.dll,单击“添加”按钮旁边的向下箭头,然后选择“添加为链接”。然后在解决方案资源管理器中选择新的7z.dll项目,alt-Enter以显示属性,并将“复制到输出目录”设置为“如果更新则复制”(或“始终复制”)。
2:将DeploymentItemAttribute
附加到您的测试类。此属性的构造函数采用单个字符串参数,该参数是要为类中的测试提供的文件的路径。它与测试项目的输出目录有关。