本文介绍了最小起订量:放大器;互操作类型:在VS2012的工作原理,在失败VS2010?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有大约500单元测试.NET库项目。所有这些测试在Visual Studio 2012年。但是运行良好,我的一些测试失败在Visual Studio 2010在这些测试失败,我使用起订量嘲笑几个互操作类型微软.Office.Interop.Excel 。测试失败立即试图访问这些嘲笑互操作类型时:

I have a .NET library project with about 500 unit tests. All these tests run fine in Visual Studio 2012. However, some of my tests fail in Visual Studio 2010. In these failing tests, I use Moq to mock several Interop Types from Microsoft.Office.Interop.Excel. The test fails immediately when attempting to access these mocked interop types:

Error: Missing method 'instance class Microsoft.Office.Interop.Excel.Range [ExcelAddIn.Core] Microsoft.Office.Interop.Excel.ListRow::get_Range()' from class 'Castle.Proxies.ListRowProxy'.

这例外意味着我忘了安装在我的模拟相应的属性的getter。这是不是这样的:

This exception implies that I forgot to setup the appropriate property getter on my mock. Which is not the case:

_listRowMock.Setup(m => m.Range).Returns(_rangeMock.Object);

现在我可以想像,起订量可能与互操作类型工作也很好。但我觉得最令人费解的是,这些测试在Visual Studio 2012中运行良好,但在Visual Studio 2010中失败

Now I can imagine that Moq might not work too well with Interop Types. But what I find most puzzling is that these tests run fine in Visual Studio 2012, but fail in Visual Studio 2010.

为什么我的Visual Studio影响我的code的行为?

Why is my Visual Studio influencing the behavior of my code?

更新:2012年3月11日

好了,我得到了它归结为这样的:

Ok, so I got it down to this:


  • 我有两个项目; Core和Core.UnitTest。核心是实际的图书馆,而Core.UnitTest是核心库的单元测试项目。

  • 这两个项目引用的Microsoft.Office.Interop.Excel与嵌入互操作类型启用。

  • 由于EIT被启用,这两个项目包括图书馆的Microsoft.Office.Interop.Excel自己的看法。视图包括了在各自的项目中使用的所有类,方法和属性。

  • 由于这两个项目使用不同的类,方法和的Microsoft.Office.Interop.Excel的属性,嵌入式类型这两个库的不同。例如。 ListRow在核心有一个指数和Range属性,而在ListRow仅Core.UnitTest具有Range属性。

  • 虽然这两种类型是不同的,不共享一个通用的接口或超类,它们的。这意味着CLR会对待他们,如果他们是相同的,可以让你跨越边界的装配使用这些类型。例如。传递到核心库的方法时ListRow从Core.UnitTest的一个实例,将正常工作。共享范围的属性将发挥作用,而缺少索引属性将抛出访问MissingMethodException。

  • 上述行为甚至嘲笑类型的作品。模拟[Excel.ListRow]的嘲笑对象跨越边界的装配时将正常工作。

  • 不幸的是,在previous点描述的行为,只有当我建立我的程序集在Visual Studio中的 2012 的作品。当我建立我的程序集在Visual Studio中的 2010 并调试我的code,可以看我的嘲笑ListRow实例被传递到我的核心项目的方法。实例越过边界装配的那一刻,所有的方法和ListRow属性失去其执行并抛出MissingMethodExceptions。

  • 现在,最有趣的部分,其实我设法通过确保嵌入式类型ListRow被对准以缓解此问题。例如。为了使编译器创建ListRow在这两个项目同样的看法,我确信,我用我的UnitTest项目完全相同的方法和属性。这意味着添加虚拟线,如:VAR假人= listRow.Index。有一次,我的编译器创建我的嵌入式ListRow类型一致的看法,该实例被允许跨越界限装配不失其执行情况。

  • I have two projects; Core and Core.UnitTest. Core is the actual library while Core.UnitTest is a unit test project of the Core library.
  • Both projects reference Microsoft.Office.Interop.Excel with Embed Interop Types enabled.
  • Because EIT is enabled, both projects include their own "view" of the Microsoft.Office.Interop.Excel library. The view includes all classes, methods and properties that are used in their respective project.
  • Because both projects use different classes, methods and properties of the Microsoft.Office.Interop.Excel, the embedded types of both libraries differ. E.g. ListRow in Core has an Index and Range property, whereas ListRow in Core.UnitTest only has the Range property.
  • Although both types are different and do not share a common interface or super class, they are equivalent. This means that the CLR will treat them as if they are the same and will allow you to use these types across assembly boundaries. E.g. an instance of ListRow from Core.UnitTest will work fine when passed to a method in the Core library. The shared Range property will function, whereas the missing Index property will throw a MissingMethodException on access.
  • The aforementioned behavior even works with mocked types. An mocked object of Mock[Excel.ListRow] will work fine when crossing the assembly boundary.
  • Unfortunately, the behavior described in the previous point only works when I build my assemblies in Visual Studio 2012. When I build my assemblies in Visual Studio 2010 and debug my code, I can see the mocked ListRow instance being passed into a method of my Core project. The moment the instance crosses the assembly boundary, all methods and properties of ListRow lose their implementation and throw MissingMethodExceptions.
  • Now for the fun part, I actually managed to mitigate this issue by ensuring that both embedded types of ListRow are aligned. E.g. in order for the compiler to create the same view of ListRow in both projects, I made sure that I used the exact same methods and properties in my UnitTest project. This means adding dummy lines like: var dummy = listRow.Index. Once I had the compiler creating identical views of my embedded ListRow type, the instance was allowed to cross assembly boundaries without losing its implementation.

问题仍然存在,但:?是什么原因导致的Visual Studio 2010和Visual Studio 2012之间的这种行为差异

The question still remains though: What causes this difference in behavior between Visual Studio 2010 and Visual Studio 2012?

更新:2012年9月11日

演示解决方案

我创建了一个小的解决方案演示效果。该解决方案包括一个图书馆和一个的UnitTest项目。与EIT两个参考Microsoft.Office.Interop.Excel.Range启用。测试工作正常VS2012,但VS2010引发MissingMethodException。在取消在测试虚拟线将使其在VS2010的工作。

I have created a small solution to demonstrate the effect. The solution consists of a library and a UnitTest project. Both reference Microsoft.Office.Interop.Excel.Range with EIT enabled. The test works fine in VS2012 but throws MissingMethodException in VS2010. Uncommenting the dummy line in the test will make it work in VS2010.

最后更新:29-12-2012

我的道歉进行更新晚了。我的一位同事找到了解决办法,但我无法重现我的机器上。在此期间我公司已做了开关到TFS2012因此这不再是我一个阻塞问题。我的同事提出的两个最重要的结论是:

My apologies for the late update. A colleague of mine found a solution, however I was unable to reproduce it on my machine. In the meantime our company has made the switch to TFS2012 so this is no longer a blocking issue for me. The two most important conclusions my colleague made were:


  • 在任何CPU平台的语义从视觉改变
    Studio 2010中到Visual Studio 2012年。这将导致不同的
    这取决于您是否使用VS2010或.dll的生成
    VS2012。

  • 引用的不同版本的Microsoft.Office.Interop.Excel的两个项目。

我检查我的项目和理顺引用,但它并没有区别。在那之后,我想在这两个VS2010和VS2012平台上不同的变化,但无法产生一个令人满意的结果。我会接受杰里米的答案,因为它是最有帮助的。谢谢大家的协助。

I checked my projects and straightened out the references, but it made no difference. After that, I tried different variations of platforms in both VS2010 and VS2012 but was unable to produce a satisfactory result. I will accept Jeremy's answer as it was the most helpful. Thank you all for your assistance.

推荐答案

编辑:这为我工作,当我尝试在Visual Studio 2012年和目标.NET 4.0,只使用.net PIA的不是COM REF。同样的解决方案并不在VS2010工作。

Edit : It works for me when I try it in Visual Studio 2012 and target .Net 4.0, only using the .Net PIA's not the COM ref. Same solution doesn't work in VS2010.

Microsoft.VisualStudio.QualityTools.UnitTestFramework.dll的和VS2012负载版本的11.0.50727.1的10.0.30319.1 VS2010负载版本的。你可以看到不同版本的模块中的窗口。

VS2010 loads version's 10.0.30319.1 of the Microsoft.VisualStudio.QualityTools.UnitTestFramework.dll's and VS2012 loads version's 11.0.50727.1. You can see the different version's in the Modules window.

我设法得到它在VS2010的工作:

下面是我的解决方案为大家提供方便。它具有所有包括起订量引用。我有Excel 2007中(即V12) - 所以请调整引用到Office 14

Here is my solution http://temp-share.com/show/Pf3Ypip62 for everyone's convenience. It has all the Moq references included. I have Excel 2007 (ie v12) - so please adjust references to Office 14.

与被测试方法该项目已通过.NET参考选项卡使用PIA 的Microsoft.Office.Interop.Excel

The Project with methods to be Tested has to use the PIA Microsoft.Office.Interop.Excel via the .Net reference tab.

在单元测试项目,你必须使用 Microsoft Excel中1X.0对象库通过COM引用标签 - 它的一个ActiveX

In the Unit Test Project you have to use the Microsoft Excel 1X.0 Object Library via the COM reference tab - its an ActiveX.

在令人困惑的事情就是在Solution Explorer中,他们都被称为:的Microsoft.Office.Interop.Excel

有是,我不知道如何要解决另外一个警告 - 你必须使用.NET 3.5框架的我其实是希望微软修复它在2012年,你发现,因为我不能工作如何在.NET 4.0的所有项目做到这一点。混合项目瞄准的.Net 3.5安培一些解决方案; 4.0为正常。

There is one other caveat that I dont know how to workaround - you have to use the .Net 3.5 framework and I was actually hoping Microsoft fixed it in 2012 as you found because I cant work how to do it with ALL projects in .Net 4.0. Some solutions with mixed projects targeting .Net 3.5 & 4.0 are ok.

我已经有很多的这种麻烦,在这里看到的How做我嘲笑避免的Excel.worksheet在使用动态也看到这个问题,我问:Mocked对象不具有在IntelliSense显示所有属性 - 在一个项目中,但有他们在其他

I've had a lot of trouble with this, see here How do I avoid using dynamic when mocking an Excel.worksheet? and also see this question I asked: Mocked object doesn't have all properties shown in Intellisense - in one project but has them in the other.

反正这是怎么得到它在2010年的工作VS我很高兴它解决了在2012年!

Anyway this is how to get it working in VS 2010. I'm glad its resolved in 2012!

这篇关于最小起订量:放大器;互操作类型:在VS2012的工作原理,在失败VS2010?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-22 08:05