1

情况如下:我正在尝试使用我称之为“TestProject”的测试项目来运行单元测试。它正在另一个项目中测试一个类,我将其称为“Class1”和“Project1”。

Project1 在运行时对各种 dll 进行一些动态延迟加载,我将其称为“TheDynamicDLLs”。Project1 通过查看相对于它自己的构建输出路径的目录来找到这些 dll。

问题的第一部分出现在 TestProject 引用 Project1 时。显然,它将新建的 Project1.dll 复制到其 OWN 构建目录,然后当 Project1.dll 在相对于其位置的路径中查找 TheDynamicDLLs 时,它找不到它们,因为它是从 TestProject 的位置运行的,而不是它的自己的。

为了解决这个问题,我去了 TestProject 的引用,右键单击 Project1 引用,然后打开它的属性。然后我将“复制本地”设置为“假”。我还确保引用的“路径”属性与 Project1 的构建路径相同。

现在我有一个新问题,我什至无法弄清楚它是什么。每当我运行单元测试时,它都会失败并报告“System.IO.FileNotFoundException:无法加载文件或程序集[信息将 Project1 命名为无法找到的程序集]”。

此外,当我尝试调试单元测试时,而不是仅仅运行它,它永远不会引发异常、抱怨或任何事情,从而阻止我找到有关该问题的任何进一步信息。我在测试报告中也找不到任何有用的信息。

这是带有名称的完整测试报告,出于保密目的,这些名称已被换掉:

Test Name:  Class1_Tests
Test FullName:  TestProject.TestClass.Class1_Tests
Test Source:    c:\Code\Solution1\Tests\TestProject\TestClass.cs : line 175
Test Outcome:   Failed
Test Duration:  0:00:00.0348455

Result Message: 
Test method TestProject.TestClass.Class1_Tests threw exception: 
System.IO.FileNotFoundException: Could not load file or assembly 'Project1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.=== Pre-bind state information ===
LOG: DisplayName = Project1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
 (Fully-specified)
LOG: Appbase = file:///C:/Code/Solution1/Tests/TestProject/bin/Debug
LOG: Initial PrivatePath = NULL
Calling assembly : TestProject, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null.
===
LOG: This bind starts in default load context.
LOG: Using application configuration file: C:\Code\Solution1\Tests\TestProject\bin\Debug\TestProject.dll.config
LOG: Using host configuration file: 
LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework\v4.0.30319\config\machine.config.
LOG: Policy not being applied to reference at this time (private, custom, partial, or location-based assembly bind).
LOG: Attempting download of new URL file:///C:/Code/Solution1/Tests/TestProject/bin/Debug/Project1.DLL.
LOG: Attempting download of new URL file:///C:/Code/Solution1/Tests/TestProject/bin/Debug/Project1/Project1.DLL.
LOG: Attempting download of new URL file:///C:/Code/Solution1/Tests/TestProject/bin/Debug/Project1.EXE.
LOG: Attempting download of new URL file:///C:/Code/Solution1/Tests/TestProject/bin/Debug/Project1/Project1.EXE.
Result StackTrace:  at TestProject.TestClass.Class1_Tests()

从日志来看,TestProject 似乎仍在尝试从其 OWN #$%^ing 构建路径加载 Project1 的 dll,尽管我明确告诉它不要复制本地。(咕噜……)

我究竟做错了什么?

4

1 回答 1

4

!!!请注意:我发布的原始问题是关于我解决更深层次问题的问题。这个答案是对更深层次问题的解决方案,而不是问题所问的问题。

进一步解释:最初的问题是当这些引用设置为“CopyLocal = false”时,如何让运行时环境正确加载引用的依赖项。

之所以问这个问题是因为我一直在设置 copylocal=false 以保持依赖 dll 在其原始构建路径中运行,即使它被加载并作为不同单元测试项目的一部分运行,以便它能够在位于相对于其构建路径的文件夹路径中的运行时。

这个答案是对第一个问题的答案,消除了首先设置 copylocal=false 的需要。因此,我不会在这里选择我的答案作为最有帮助的答案。如果有人对直接问题有答案,他们仍应将其发布以帮助可能因与我不同的原因而在该问题上苦苦挣扎的人。

也就是说,这是我需要设置 copylocal=false 的原因的解决方案

  1. 将 TheDynamicDLLs 添加到 Project1,但不作为参考。只需在解决方案资源管理器中右键单击 Project1 并选择“添加现有项目”,然后浏览到每个 dll 位置并将其添加为链接。(添加为链接很重要,以便在由其 DynamicDLLProject 重建时刷新它)。
  2. 右键单击 Project1 中新添加的项目并选择“属性”。将“Bu​​ild Action”设置为“None”,并将“Copy to Output Directory”设置为“Copy if newer”“Copy always”
  3. 对 Project1 将/可能在运行时加载的每个动态 dll 重复步骤 1 和 2。
  4. 当然,在 TestProject 中,我将 Project1 引用设置回“Copy Local = True”。

这样做的效果是,虽然动态 dll 并未实际引用或编译到 Project1 中(应该在 Project1 运行时防止它们急切加载),但任何引用 Project1 并将其 dll 复制到其输出路径的项目,还将复制作为该项目输出的一部分添加的项目(在本例中为 TheDynamicDLLs)。

我希望这可以帮助任何有这个问题的人,原因与我类似。

于 2014-07-22T22:26:16.017 回答