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

时间:2015-09-24 18:09:03

标签: c# unit-testing visual-studio-2015 microsoft-fakes .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()
    {
    }
}
  • 验证测试通过

  • 右键单击 Microsoft.Practices.Unity 参考,然后选择&#34;添加假装配&#34;

  • 重新运行测试

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

  

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

     

结果StackTrace:

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



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

大量的摆弄表明将测试项目重新定位到.NET 4.5&#34;修复&#34;这个问题,对我来说是一个不起作用的问题,因为another问题我几个星期后发布了。

几乎所有假货设置(代码合约等)的摆弄都更加难以解决。

非常感谢有关此问题的任何建议。

1 个答案:

答案 0 :(得分:2)

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

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

这些事情通常对于运行和调试并不重要,因为有几个层可以确保次要版本差异不重要,或者您可以无声地切换到声明兼容的代码用。

但是,当你使用Fakes时,&#34;系统&#34;将原始代码注入您的(包括第三方库),这意味着它会跳过大多数检查 - 否则无法正常工作。但是,当实际运行代码的时候,引擎(虚拟机)必须对它自身的安全性/完整性进行一些检查,如果它看起来像声明,那么它往往会变得偏执和纾困。 ; t足够紧密。

这就是为什么有人询问涉及的议会是强名还是签名的原因。这是&#34; system&#34;的唯一保证级别。真的会相信。没有它,它会做一定程度的猜测,而对于正常运行而言,如果对代码注入有很多重要的话,它们并不重要。

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

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

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