我想模拟Microsoft.Office.Interop.Excel.Range以及之后能够获取属性Row(Range的第一行索引)。 Moq v 4.1.1309.1617 / nunit.framework v 2.6.3.13283 在我的单元测试中,我尝试按如下方式设置模拟的行为:
var moqRowSelected = new Mock<Range>();
const int row = 1;
moqRowSelected.SetupGet(x => x.Row).Returns(row);
moqSheetBase.SetupProperty(x => x.RowSelected, moqRowSelected.Object);
在单元测试的代码中,我使用Range如下:
var iRow = PlanningSheet.RowSelected.Row;
Range row = sheet.Rows[iRow];
测试运行时会产生以下异常:
错误:缺少方法'实例int32 [My.Example.Implementation.MyClass] 来自类的Microsoft.Office.Interop.Excel.Range :: get_Row()' 'Castle.Proxies.RangeProxy'。
如何成功实施此模拟?任何人都可以帮助我,谢谢。
答案 0 :(得分:3)
我认为你已经正确地模拟了 PlanningSheet.RowSelected 引用的对象,因此 iRow 应该是正确的。但是,您没有正确地模拟 sheet.Rows
返回的范围让我们重写正在测试的代码,如下所示
var iRow = PlanningSheet.RowSelected.Row;
Range rows = sheet.Rows;
Range row = rows.get_Range(iRow);
我敢打赌,变量 rows 中包含的模拟不包含get_Range()的实现,它是对索引属性进行优化的方法。
就个人而言,我因为模拟问题而避免索引属性 Mocking indexed property
所以这里的代码似乎可以在你的情况下启用模拟。请注意,我无法访问PlanningSheet的类型,因此我将属性RowSelected引用的对象作为方法的参数传递 CodeUnderTest
private Range CodeUnderTest(Range rowSelected, Worksheet worksheet)
{
int index = rowSelected.Row;
var range = worksheet.Rows.get_Range(index);
return (Range) range;
}
[TestMethod]
public void MySampleTest()
{
var moqRowSelected = new Mock<Range>();
const int row = 1;
moqRowSelected.SetupGet(x => x.Row).Returns(row);
var moqRows = new Mock<Range>();
moqRows.Setup(x => x.get_Range(It.Is<object>( (i) => (int) i==row),It.IsAny<object>())).Returns(moqRowSelected.Object);
var mockWorksheet = new Mock<Worksheet>();
mockWorksheet.SetupGet(w => w.Rows).Returns(moqRows.Object);
var result = CodeUnderTest(moqRowSelected.Object, mockWorksheet.Object);
Assert.IsNotNull(result);
}
最后,您将看到必须在模拟中为方法 get_Range 提供所有参数。这是因为如果你不这样做,它将无法编译。错误很明显表达式树不能包含使用可选参数的调用或调用。