I want to mock the Microsoft.Office.Interop.Excel.Range (and the other Microsoft.Office.Interop.Excel interfaces) to unit test my application. I'm using Moq 4.0.10827 with .NET 4 in C#.
In my unit test, I attempt to set up the behavior of the mock as follows:
var range = new Mock<Microsoft.Office.Interop.Excel.Range>();
range.Setup(r => r.get_Value(1)).Returns("Something");
var classBeingTested = new MyClass(range.Object);
In the code being unit tested, I'm using the Range as follows:
public MyClass(Range range)
{
var value = range[1].ToString();
}
When the test runs, it produces the following exception:
Error: Missing method 'instance object [My.Example.Implementation.MyClass] Microsoft.Office.Interop.Excel.Range::get__Default(object,object)' from class 'Castle.Proxies.RangeProxy'.
How can I implement this mocking successfully? I realize that isolating the Excel Interop functionality with a pattern such as https://stackoverflow.com/a/9486226/1548950 is a potential solution; however, I'd be happier with being able to create mocks from the Microsoft.Office.Interop.Excel interfaces.
EDIT: More details on this issue
OK, this is strange. I've created a project to test the suggestion by jimmy_keen. It works. However, when I use the same suggestion to test the project I had issues with, it throws the following exception:
Error: Missing method 'instance object [My.Example.Implementation.MyClass] Microsoft.Office.Interop.Excel.Range::get__Default(object,object)' from class 'Castle.Proxies.RangeProxy'.
Since jimmy_keen's suggestion worked fine on other projects, I started suspecting that there is something wrong with the project I'm testing the code with. So, I created a test solution that demonstrates the problem in detail: http://www7.zippyshare.com/v/70834394/file.html
The root of the problem seems to be that the project contains another class (that is not being unit tested) with essentially the following code:
using Microsoft.Office.Interop.Excel;
namespace Project
{
public class UnTestedClass
{
public UnTestedClass(Worksheet sheet)
{
var foo = sheet.Range["Description"].Column;
}
}
}
I don't understand why this causes the issue, because I'm not using UnTestedClass in the unit test at all. Am I missing something in how I should use Moq, or have I stumbled upon a bug?
Your code accesses indexer, and that's what you need to mock:
var range = new Mock<Microsoft.Office.Interop.Excel.Range>();
range.Setup(r => r[1, It.IsAny<object>()]).Returns("something");
Note that Range
indexer actually takes two parameters - hence the It.IsAny<object>()
constraint in call.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With