Reputation: 1
I want to mock the Microsoft.Office.Interop.Excel.Range and after to be able to get property Row (index of first Row of Range). Moq v 4.1.1309.1617 / nunit.framework v 2.6.3.13283 In my unit test, I attempt to set up the behavior of the mock as follows:
var moqRowSelected = new Mock<Range>();
const int row = 1;
moqRowSelected.SetupGet(x => x.Row).Returns(row);
moqSheetBase.SetupProperty(x => x.RowSelected, moqRowSelected.Object);
In the code being unit tested, I'm using the Range as follows:
var iRow = PlanningSheet.RowSelected.Row;
Range row = sheet.Rows[iRow];
When the test runs, it produces the following exception:
Error: Missing method 'instance int32 [My.Example.Implementation.MyClass] Microsoft.Office.Interop.Excel.Range::get_Row()' from class 'Castle.Proxies.RangeProxy'.
How can I implement this mocking successfully? Can any one help me, Thanks.
Upvotes: 0
Views: 1267
Reputation: 4545
I think you have correctly mocked the object referenced by PlanningSheet.RowSelected, therefore the iRow should be correct. However you do not have correctly mocked the Range returned by sheet.Rows
Let us rewrite the code under test as follow
var iRow = PlanningSheet.RowSelected.Row;
Range rows = sheet.Rows;
Range row = rows.get_Range(iRow);
I bet that the mock contained in the variable rows does not contain a implementation for get_Range() whose is the method behing the indexed property.
Personally, I avoid indexed property because of mocking issue see Mocking indexed property
So here is the code that seems to enable mocking in your case. Note that I do not have access to the type of PlanningSheet so I pass the object referenced by the property RowSelected as a parameter of the method 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);
}
Finally you will see that you must provide all the parameters to the method get_Range in the mock. This is because if you do not do this, it will not compile. The error is clear An expression tree cannot contain a call or invocation that uses optional arguments.
Upvotes: 3