如何避免使用dynamic模拟Excel.worksheet时?

我试图用NSubstitute或其他模拟框架和MSTest(Visual Studio 2010)来模拟Excel电子表格。 我不确定是否有比这更好的方法 – 这不适合testing:

这是一个例子(这是所有的原型代码,而不是很干净):

int[] lowerBounds = { 1, 1 }; int[] lengths = { 2, 2 }; //Initialize a 1-based array like Excel does: object[,] values = (object[,])Array.CreateInstance(typeof(object), lengths, lowerBounds); values[1,1] = "hello"; values[2,1] = "world"; //Mock the UsedRange.Value2 property sheet.UsedRange.Value2.Returns(values); //Test: GetSetting(sheet, "hello").Should().Be("world"); //FluentAssertions 

到目前为止,这么好:如果GetSetting方法与我的testing在同一个项目中 ,则通过。 但是当GetSetting在我的VSTO Excel-Addin项目中时,GetSetting函数的第一行中将失败并出现以下错误:

 System.MissingMethodException: Error: Missing method 'instance object [MyExcel.AddIn] Microsoft.Office.Interop.Excel.Range::get_Value2()' from class 'Castle.Proxies.RangeProxy'. 

作为参考,GetSetting从工作表中的columnA获取一个值,并返回columnB中的值。

 public static string GetSetting(Excel.Worksheet sheet, string settingName) { object[,] value = sheet.UsedRange.Value2 as object[,]; for (int row = 1; row <= value.GetLength(1); row++) { if (value[1, row].ToString() == settingName) return value[2, row].ToString(); } return ""; } 

最后有趣的是如果我重新定义我的方法的签名如下:
公共静态stringGetSetting( dynamic表,stringsettingName)
它在VSTO项目中工作。

那么发生了什么事情,做这样的事情的最好方法是什么?

谢谢!

VS2012更新: Moq&Interoptypes:在VS2012中工作,在VS2010中失败?

首先:有些东西已经改变了: 如何避免在模拟Excel.worksheet时使用dynamic模式?

我遇到了同样的问题使用NSubstitute嘲笑Excel对象。 dynamic解决了问题,就像你提到的一样。 但是我想find根本原因。


当您的项目有一个引用Microsoft.Office.Interop.Excel.Extensions.dll您需要检查是否可见embedded互操作types属性。 如果这意味着你的目标。NET 4.0(我可以从dynamic关键字猜测)。

您可以将testing项目定位到.Net 4.0,但您需要将VSTO Project .Net框架更改回3.5。 那么你可能不得不做一些明确的投射,并完全限定的东西来摆脱这些错误:

C#Office Excel Interop“对象不包含”错误的定义 ,这里有几个例子:

.Net 4.0:

 if (tmpsheetName == xlApp.ActiveSheet.Name) 

.Net 3.5相当于

 Worksheet activeSheet = (Worksheet)xlApp.ActiveSheet; if (tmpsheetName == activeSheet.Name) 

另一个例子:

 rn.Select(); 

.Net 4.0

 xlApp.Selection.HorizontalAlignment = Constants.xlCenter; xlApp.Selection.Font.Bold = true; xlApp.Selection.Merge(); 

.Net 3.5相当于

 rn.HorizontalAlignment = Constants.xlCenter; rn.Font.Bold = true; rn.Merge(); 

按照上面的例子继续修复所有.net 3.5 vs 4.0语法错误。 不要忘记删除dynamic参数types并将其replace为原始的Worksheet 。 最后再次启动testing,它会通过!

鉴于我所经历的与Microsoft.CSharp.DLL在这个线程中的所有悲伤我的意见testing与Mocking框架的VSTO .Net 4.0项目不起作用。

事实certificate,使用任何基于城堡的框架(nsubstitute,ninject等)来嘲讽非常复杂的COM互操作对象(如Excel对象或InDesign对象)并不能提供足够的性能启动。 testing运行时间仍然可以在几秒钟内测量。 (通过数十或数百次的testing,这使得unit testing仍然太慢,不能在TDDtesting原则下运行。)

testingExcel逻辑应该被认为是一个集成testing,因此,对实际的Excel对象运行应该没问题,在这种情况下嘲笑不是很有用。 结果将更有用的testing对实际的对象。

testing到放置在Excel和应用程序之间的抽象层将允许快速testing应用程序逻辑。 在集成testing中testing抽象层到excel应该足以彻底地testing应用程序。