带伪造的unit testing中的Visual Studio 2015 InvalidProgramException

我正在使用Visual Studio 2015 Enterprise RTM为使用Unity Container的项目编写unit testing。

我发现为Unity添加一个fakes程序集的简单行为,甚至实际上不使用伪造,足以产生这个exception:

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

请考虑以下步骤来重现:

  • 使用Visual Studio 2015 Enterprise RTM创建面向.NET 4.6的unit testing项目

  • 添加NuGet包“Unity”版本3.5.1404.0

  • 添加NuGet包“CommonServiceLocator”1.2.0版

  • 像这样写一个unit testing:

[TestClass] public class UnitTest1 : IDisposable { [TestMethod] public void TestMethod1() { new ResolvedArrayParameter(new IDisposable[] {this}); } void IDisposable.Dispose() { } } 
  • validation测试通过

  • 右键单击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)
在Microsoft.Practices.Unity.ResolvedArrayParameter`1..ctor(Object [] elementValues)
在C:\ temp \ UnitTestProject11 \ UnitTestProject11 \ UnitTest1.cs中的UnitTestProject11.UnitTest1.TestMethod1():第13行
结果消息:
测试方法UnitTestProject11.UnitTest1.TestMethod1抛出exception:
System.InvalidProgramException:公共语言运行时检测到无效程序。

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

大量的摆弄显示,将测试项目重新定位到.NET 4.5“修复”了这个问题,由于我在几周后发布的另一个问题,这对我来说是一个非首发。

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

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

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

这个问题没有灵丹妙药。 注入假货时,您需要知道(挖掘)项目中所有连接部件的CLR版本兼容性。 请注意,“兼容性”可能只是明显的问题,但更常见的是,最终代码的生成方式和虚拟机版本的细微差别问题。

这些事情通常对于运行和调试无关紧要,因为有几个层确保次要版本差异无关紧要,或者您无法切换到声明与之兼容的代码。

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

这就是为什么有人询问涉及的议会是强名还是签名的原因。 这是“系统”真正信任的唯一保证级别。 如果没有它,它将进行一定程度的猜测,而对于正常运行而言,如果对代码注入有很多重要的事情则无关紧要。

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

当您将味道切换回4.5时错误消失的事实告诉您,所涉及的某些程序集对于4.6来说不够“接近”,或者可能存在一些代码注入的故障,这些故障是由您未接受的更新修复的然而。

是的,它涉及很多痛苦,但这是想要进入边境的代价。