带伪造的单元测试中的Visual Studio 2015 InvalidProgramException

42v*_*ons 27 c# unit-testing microsoft-fakes visual-studio-2015 .net-4.6

我正在使用Visual Studio 2015 Enterprise RTM为使用Unity Container的项目编写单元测试.

我发现为Unity添加伪造程序集的简单行为,甚至实际上不使用伪造,足以生成此异常:

System.InvalidProgramException:公共语言运行时检测到无效程序.



请考虑以下步骤来重现:

  • 使用Visual Studio 2015 Enterprise RTM创建面向.NET 4.6的单元测试项目

  • 添加NuGet包"Unity"版本3.5.1404.0

  • 添加NuGet包"CommonServiceLocator"1.2.0版

  • 像这样写一个单元测试:

[TestClass]
public class UnitTest1 : IDisposable
{
    [TestMethod]
    public void TestMethod1()
    {
        new ResolvedArrayParameter<IDisposable>(new IDisposable[] {this});
    }

    void IDisposable.Dispose()
    {
    }
}
Run Code Online (Sandbox Code Playgroud)
  • 验证测试通过

  • 右键单击Microsoft.Practices.Unity参考并选择"Add Fakes Assembly"

  • 重新运行测试

  • 观察以下显着的测试失败:

测试名称:TestMethod1
测试FullName:UnitTestProject11.UnitTest1.TestMethod1
测试源:c:\ temp\UnitTestProject11\UnitTestProject11\UnitTest1.cs:第12行
测试结果:失败
测试持续时间:0:00:00.0572447

结果StackTrace:

在Microsoft.Practices.Unity.ResolvedArrayParameter..ctor(类型arrayParameterType,Type elementType,Object [] elementValues)
,
位于UnitTestProject11.UnitTest1的Microsoft.Practices.Unity.ResolvedArrayParameter`1..ctor(Object [] elementValues). C:\ temp\UnitTestProject11\UnitTestProject11\UnitTest1.cs中的TestMethod1():第13行
结果消息:
测试方法UnitTestProject11.UnitTest1.TestMethod1引发异常:
System.InvalidProgramException:公共语言运行时检测到无效程序.



这个问题最显着的特点是显然假货甚至不需要直接出现在代码中就无法显示.

大量的小提琴显示,将测试项目重新定位到.NET 4.5"修复"了这个问题,这对我来说是一个非首发因素,因为我在几周后发布了另一个问题.

几乎所有的假货设置(代码合同等)都更难以解决问题.

关于这个问题的任何建议都将非常感谢.

小智 2

唯一的通用解决方案是确保所有部分与您正在使用的 CLR 版本非常匹配,并且 VS 具有最新更新。

这个问题没有灵丹妙药。当您注入假货时,您需要了解(挖掘)项目中连接的所有部分的确切 CLR 版本兼容性。请注意,“兼容性”可能只是清单问题,但更常见的是,它们是如何生成最终代码以及针对哪个虚拟机版本的细微差别的问题。

这些事情通常对于运行和调试来说并不重要,因为有几个层可以确保较小的版本差异无关紧要,或者您可以静默切换到您的代码声明兼容的任何内容。

但是,当您使用 Fakes 时,“系统”会将原始代码注入您的代码(其中包括涉及的第 3 方库),这意味着它会跳过大多数检查 - 否则无法工作。但是,当实际运行代码时,引擎(虚拟机)必须对其自身的安全性/完整性进行一些检查,如果声明看起来不够匹配,它往往会变得偏执并退出。

这就是为什么有人问所涉及的程序集是否是强命名或签名的原因。这是“系统”真正信任的唯一保证级别。如果没有它,它将进行一定程度的猜测,虽然对于代码注入很重要,但对于正常运行来说基本上无关紧要。

我仍然没有谈论可能的实际问题 - 这一切都假设实际代码很好,只是声明很混乱。您可以尝试使用它,但这需要花费大量时间和精力。检查是否可以获得更匹配的程序集版本要容易得多。

当您将风格切换回 4.5 时,错误消失了,这一事实告诉您,要么涉及的某些程序集对于 4.6 来说不够“接近”,要么代码注入可能存在一些故障,这些故障已通过您尚未采用的更新修复然而。

是的,这会带来很多痛苦,但这就是想要处于前沿的代价。