使用Mock将属性Row设置为Mocked Microsoft.Office.Interop.Excel.Range

时间:2013-11-28 12:11:27

标签: c# excel unit-testing nunit moq

我想模拟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'。

如何成功实施此模拟?任何人都可以帮助我,谢谢。

1 个答案:

答案 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 提供所有参数。这是因为如果你不这样做,它将无法编译。错误很明显表达式树不能包含使用可选参数的调用或调用