简体   繁体   English

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

[英]Visual Studio 2015 InvalidProgramException in Unit Test With Fakes

I am using Visual Studio 2015 Enterprise RTM to write unit tests for a project that uses Unity Container . 我正在使用Visual Studio 2015 Enterprise RTM为使用Unity Container的项目编写单元测试。

I have discovered that the simple act of adding a fakes assembly for Unity, not even actually using the fake, is sufficient to generate this exception: 我发现为Unity添加伪造程序集的简单行为,甚至实际上不使用伪造,足以生成此异常:

System.InvalidProgramException: Common Language Runtime detected an invalid program. System.InvalidProgramException:公共语言运行时检测到无效程序。



Consider the following steps to reproduce: 请考虑以下步骤来重现:

  • Using Visual Studio 2015 Enterprise RTM create a Unit Test project targeting .NET 4.6 使用Visual Studio 2015 Enterprise RTM创建面向.NET 4.6的单元测试项目

  • Add the NuGet package "Unity" version 3.5.1404.0 添加NuGet包“Unity”版本3.5.1404.0

  • Add the NuGet package "CommonServiceLocator" version 1.2.0 添加NuGet包“CommonServiceLocator”1.2.0版

  • Write a single unit test like so: 像这样写一个单元测试:

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

    void IDisposable.Dispose()
    {
    }
}
  • Verify the test passes 验证测试通过

  • Right click on the Microsoft.Practices.Unity reference and choose "Add Fakes Assembly" 右键单击Microsoft.Practices.Unity参考并选择“Add Fakes Assembly”

  • Re-run the test 重新运行测试

  • Observe the following remarkable test failure: 观察以下显着的测试失败:

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

Result StackTrace: 结果StackTrace:

at Microsoft.Practices.Unity.ResolvedArrayParameter..ctor(Type arrayParameterType, Type elementType, Object[] elementValues) 在Microsoft.Practices.Unity.ResolvedArrayParameter..ctor(类型arrayParameterType,Type elementType,Object [] elementValues)
at Microsoft.Practices.Unity.ResolvedArrayParameter`1..ctor(Object[] elementValues) 在Microsoft.Practices.Unity.ResolvedArrayParameter`1..ctor(Object [] elementValues)
at UnitTestProject11.UnitTest1.TestMethod1() in c:\\temp\\UnitTestProject11\\UnitTestProject11\\UnitTest1.cs:line 13 在C:\\ temp \\ UnitTestProject11 \\ UnitTestProject11 \\ UnitTest1.cs中的UnitTestProject11.UnitTest1.TestMethod1():第13行
Result Message: 结果消息:
Test method UnitTestProject11.UnitTest1.TestMethod1 threw exception: 测试方法UnitTestProject11.UnitTest1.TestMethod1抛出异常:
System.InvalidProgramException: Common Language Runtime detected an invalid program. System.InvalidProgramException:公共语言运行时检测到无效程序。



The most extraordinary feature of this problem is evidently fakes don't even need to appear directly in the code for the failure to manifest. 这个问题最显着的特点是显然假货甚至不需要直接出现在代码中就无法显示。

An extensive amount of fiddling reveals that retargeting the test project to .NET 4.5 "fixes" the problem, which is a non-starter for me because of another issue I posted some weeks back. 大量的摆弄表明,将测试项目重新定位到.NET 4.5“修复”了这个问题,这对我来说是一个非首发因素,因为我在几周后发布了另一个问题。

Even more fiddling with virtually all fakes settings (code contracts, etc.) yielded no solution. 几乎所有的假货设置(代码合同等)都更难以解决问题。

Any advice on this issue would be very much appreciated. 关于这个问题的任何建议都将非常感谢。

The only general solution is to make sure that all parts match the version of CLR you are using very closely and that VS has the latest updates. 唯一的通用解决方案是确保所有部件都与您正在使用的CLR版本匹配,并且VS具有最新更新。

There is no magic bullet for this problem. 这个问题没有灵丹妙药。 You need to know (dig out) the exact CLR version compatibility of all parts that are connected in your project when you inject fakes. 在注入假货时,您需要知道(挖掘)项目中所有连接部件的CLR版本兼容性。 Mind you that "compatibility" might be just the matter of manifest but more frequently they are the matter of nuances of how was/is the final code generated and for which version of the virtual machine. 请注意,“兼容性”可能只是明显的问题,但更常见的是,最终代码生成方式和虚拟机版本的细微差别。

These things normally don't matter for running and debugging since there are several layers that make sure that minor version differences either don't matter or you get a silent switch to whatever your code is declared to be compatible with. 这些事情通常对于运行和调试无关紧要,因为有几个层可确保次要版本差异无关紧要,或者您无法切换到声明与其兼容的代码。

But, when you use Fakes, the "system" injects raw code into your (which includes 3rd party libraries involved) and that means that it skips most checks - couldn't work otherwise. 但是,当您使用Fakes时,“系统”会将原始代码注入您的(包括第三方库),这意味着它会跳过大多数检查 - 否则无法工作。 But, when the time comes to actually run the code, the engine (virtual machine) has to do some checks for it's own safety/integrity and it tends to get paranoid and bail out if it looks like declarations don't match closely enough. 但是,当实际运行代码时,引擎(虚拟机)必须对其自身的安全性/完整性进行一些检查,如果声明看起来不够匹配,它往往会变得偏执和纾困。

This is the reason why someone asked whether assemblies involved are strongnamed or signed. 这就是为什么有人询问涉及的议会是强名还是签名的原因。 That's the only level of guarantee that "system" will really trust. 这是“系统”真正信任的唯一保证级别。 Without that it will do a degree of guessing and while it mostly doesn't matter for normal runs if matters a lot for code injection. 如果没有它,它将进行一定程度的猜测,而对于正常运行而言,如果对代码注入很重要的话,这通常无关紧要。

I'm still not talking possible real problems - this is all assuming that actual code is fine and just declarations are confused. 我仍然没有谈论可能存在的实际问题 - 这都是假设实际代码很好并且只是声明混淆了。 You could try to play with that but it would take a lot of time and effort. 你可以尝试使用它,但这需要花费大量的时间和精力。 Much easier to go checking if you can get versions of assemblies that are better matching. 更容易检查是否可以获得更好匹配的程序集版本。

The fact that errors vanished when you switched your flavor back to 4.5 tells you that either some of the assemblies involved are not "close enough" for 4.6 or there can be some glitches with code injection that were fixed by updates you haven't taken in yet. 当您将味道切换回4.5时,错误消失的事实告诉您,所涉及的某些程序集对于4.6来说不够“接近”,或者可能存在一些代码注入的故障,这些故障是由您未接受的更新修复的然而。

Yes it involves a lot of pain but that's the price of wanting to be at the frontier. 是的,它涉及很多痛苦,但这是想要进入前沿的代价。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Visual Studio 2019 单元测试因 InvalidProgramException 而失败 - Visual Studio 2019 unit test fails with InvalidProgramException Visual Studio 2015单元测试不一致 - Visual Studio 2015 Unit Test Inconsistency Visual Studio 2015如何分析单个单元测试 - Visual studio 2015 how to profile a single unit test UWP应用程序的单元测试无法在Visual Studio 2015上运行 - Unit test for UWP app failed to run on Visual Studio 2015 如何在Visual Studio 2015中并行执行单元测试用例 - How to execute the unit test cases parallel in visual studio 2015 在 Visual Studio IDE 中运行测试时,单元测试通过,但在使用 vstest.console.exe 和 Microsoft Fakes 时失败 - Unit test passes when running the test from within Visual Studio IDE but fails when using vstest.console.exe and Microsoft Fakes 使用 Visual Studio 2015 Intellitetest 进行参数化单元测试 - Parameterized Unit Tests with Visual Studio 2015 Intellitest 如何为Visual Studio 2015 RC / .NET Core项目创建单元测试? - How to I create a unit test for a Visual Studio 2015 RC / .NET Core project? 单元测试,NUnit或Visual studio? - Unit test, NUnit or Visual studio? 将表单添加到Visual Studio 2015负载测试 - Adding a Form to Visual Studio 2015 Load Test
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM