相关疑难解决方法(0)

Moq和Interop类型:在VS2012中工作,在VS2010中失败?

我有一个.NET库项目,大约有500个单元测试.所有这些测试在Visual Studio 2012中运行良好.但是,我的一些测试在Visual Studio 2010中失败.在这些失败的测试中,我使用Moq来模拟几个Interop类型Microsoft.Office.Interop.Excel.尝试访问这些模拟的互操作类型时,测试立即失败:

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

这个异常意味着我忘了在mock上设置适当的属性getter.事实并非如此:

_listRowMock.Setup(m => m.Range).Returns(_rangeMock.Object);
Run Code Online (Sandbox Code Playgroud)

现在我可以想象Moq对于Interop类型可能效果不佳.但我发现最令人费解的是,这些测试在Visual Studio 2012中运行良好,但在Visual Studio 2010中失败.

为什么我的Visual Studio会影响我的代码行为?

更新:2012年3月11日

好的,所以我明白了:

  • 我有两个项目; Core和Core.UnitTest.Core是实际的库,而Core.UnitTest是Core库的单元测试项目.
  • 这两个项目都引用了Microsoft.Office.Interop.Excel并启用了嵌入互操作类型.
  • 由于启用了EIT,因此两个项目都包含自己的Microsoft.Office.Interop.Excel库"视图".该视图包括其各自项目中使用的所有类,方法和属性.
  • 由于两个项目都使用Microsoft.Office.Interop.Excel的不同类,方法和属性,因此两个库的嵌入类型不同.例如,Core中的ListRow具有Index和Range属性,而Core.UnitTest中的ListRow仅具有Range属性.
  • 虽然两种类型都不同,并且不共享公共接口或超类,但它们是等效的.这意味着CLR会将它们视为相同,并允许您跨程序集边界使用这些类型.例如,Core.UnitTest中的ListRow实例在传递给Core库中的方法时可以正常工作.共享的Range属性将起作用,而缺少的Index属性将在访问时抛出MissingMethodException.
  • 上述行为甚至适用于模拟类型.Mock [Excel.ListRow]的模拟对象在跨越装配边界时可以正常工作.
  • 不幸的是,前一点中描述的行为仅在我在Visual Studio 2012中构建程序集时才有效.当我在Visual Studio 2010中构建程序集并调试我的代码时,我可以看到模拟的ListRow实例被传递到我的Core项目的方法中.实例越过程序集边界的那一刻,ListRow的所有方法和属性都会丢失它们的实现并抛出MissingMethodExceptions.
  • 现在,对于有趣的部分,我实际上通过确保两个嵌入类型的ListRow对齐来设法缓解此问题.例如,为了让编译器在两个项目中创建相同的ListRow视图,我确保在UnitTest项目中使用了完全相同的方法和属性.这意味着添加虚拟行,如:var dummy = listRow.Index.一旦我让编译器创建了我的嵌入式ListRow类型的相同视图,就允许该实例跨越程序集边界而不会丢失其实现.

问题仍然存在:是什么导致Visual Studio 2010和Visual Studio 2012之间的行为差​​异?

更新:2012年9月11日

演示解决方案:http://temp-share.com/show/KdPf6066h

我已经创建了一个小解决方案来演示效果.该解决方案由一个库和一个UnitTest项目组成.两者都引用了Microsoft.Office.Interop.Excel.Range并启用了EIT.该测试在VS2012中正常工作,但在VS2010中抛出MissingMethodException.在测试中取消注释虚拟线将使其在VS2010中工作.

最终更新:2012年12月29日

我为最新的更新道歉.我的一位同事找到了解决方案,但是我无法在我的机器上重现它.与此同时,我们公司已经转向TFS2012,因此这不再是我的阻塞问题.我的同事做出的两个最重要的结论是:

  • "Any CPU"平台的语义已从Visual Studio 2010更改为Visual Studio 2012.这将导致生成不同的.DLL,具体取决于您使用的是VS2010还是VS2012.
  • 这两个项目都引用了Microsoft.Office.Interop.Excel的不同版本.

我检查了我的项目并理顺了参考文献,但没有任何区别.之后,我在VS2010和VS2012中尝试了不同的平台变体,但无法产生令人满意的结果.我会接受杰里米的回答,因为这是最有帮助的.谢谢大家的帮助.

c# moq visual-studio-2010 excel-interop visual-studio-2012

11
推荐指数
1
解决办法
1854
查看次数