Can't load DLL while executing tests with MS-Test
Asked Answered
A

4

5

In my program, I use SevenZipSharp to generate zip files. SevenZipSharp is a managed DLL which loads another DLL, 7z.dll. I am manually setting SevenZipSharp's path to 7z.dll using SevenZipCompressor.SetLibraryPath.

When I execute my program in Debug mode, this all works fine, and it generates the zip file as nice as you please. However, when I execute my unit tests with mstest, SevenZipSharp always gives me the following error:

Test method threw exception: SevenZip.SevenZipLibraryException: Can not load 7-zip library or internal COM error! Message: failed to load library..

I suspect that MSTest might be doing something that is preventing SevenZipSharp from being able to load 7z.dll, like running in a security-tight sandbox (or something. I'm new to C# and MSTest...)

Does anyone have an idea about what might be happening?

Thank you!

Avram answered 30/8, 2011 at 21:49 Comment(2)
What, exactly, are you setting the path too? If it's relative, change it to a fully qualified path name.Submissive
Related post - How can I get “Copy to Output Directory” to work with Unit Tests?Watts
D
6

Though the question posits a questionable scenario, the general problem of MSTest not loading required DLLs seems to be a common one, deserving of a less dismissive answer.

  1. By default MSTest will copy the assemblies it believes are required by the test container to the Out folder of the default results folder, which changes for each run.

  2. MSTest does not always automatically infer the necessary assemblies correctly; if there is no explicit direct reference to an assembly it won't be copied. Also, native DLLs are typically not detected.

  3. I am not aware of a direct option to set the MSTest search path. You can determine the search path using procmon.exe as suggested above (it is basically the standard Windows DLL search).

  4. Unintuitively, the default search path does not include the launch directory and I think this is a cause of confusion. When the tests are running the current directory is the test results "Out" directory, not the MSTest launch directory.

However, it is possible to control MSTest search behaviour (and the copying behaviour) with a test settings file. You can easily create and edit these through Visual Studio (see the Test menu) and then specify the created settings file on the MSTest command line. You can use different settings files for Visual Studio and MSTest.

By this means you can control exactly what DLLs are copied to your test directory. See Create Test Settings to Run Automated Tests from Visual Studio to get more information on this.

Of course, DLL load failures may be due to missing dependencies, and the DLL mentioned in the error message may itself be present. You can use the dependency viewer or procmon to pick up unexpected dependencies in DLLs.

Detestation answered 29/8, 2014 at 1:25 Comment(1)
This answer was extremly helpful. For me what worked was to open the problematic reference properties, checked "Copy Local", rebuild and saw it worked, then I unchecked the "Copy Local" and since then it just continued to work.Arborization
R
4

Visual Studio 2017 (and possibly 2015) provides two new ways to indicate that a native dll or other file is required by your tests without the need for a test settings file:

1: Add a link to the dll to your test project and tell VS to copy it to the output directory. Right-click the project in Solution Explorer and choose Add > Existing Item. Browse to 7z.dll, click the down arrow next to the Add button, and choose Add as Link. Then select the new 7z.dll item in Solution Explorer, alt-Enter to bring up Properties, and set "Copy to Output Directory" to "Copy if newer" (or "Copy always").

2: Attach a DeploymentItemAttribute to your test class. This attribute's constructor takes a single string argument, which is the path to the file you want to make available to tests in the class. It is relative to the test project's output directory.

Resuscitator answered 23/1, 2018 at 15:20 Comment(0)
A
2

Consider using Process Monitor (aka procmon.exe) from the excellent SysInternals tools to monitor your test harness (MSTest). It will show you where the executable is looking for 7z.dll.

Arlie answered 30/8, 2011 at 22:3 Comment(0)
E
0

Are you sure you want your unit tests to involve external libraries? Ideally you should have mechanisms to replace external stuff with e.g. mock objects, because testing external libraries like that actually turns your test into an integration test.

For popular libraries such as SevenZipSharp you can assume that it is properly tested, and you can have manual integration tests to verify that it performs correctly in your program.

I would consider getting rid of that dependency through dependency injection, mocking frameworks, etc, and let your unit tests solely test your own code.

Investigate the factory method or abstract factory design patterns for tips on how to easily replace such dependencies.

A good start would be to create your own ICustomZipInterface, and use the wrapper pattern to encapsulate your zip logic for production code. In your unit tests, replace that wrapper class with a dummy implementation. The dummy implementation might for example record how you access your zip component and you could use that information to validate your code, rather than checking if a zip file is actually created.

Eipper answered 30/8, 2011 at 22:10 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.