我想模拟Microsoft.Office.Interop.Excel.Range(以及其他Microsoft.Office.Interop.Excel接口)来对我的应用程序进行单元测试。我在C#中使用Moq 4.0.10827和.NET 4。
在我的单元测试中,我尝试按如下方式设置模拟的行为:
var range = new Mock<Microsoft.Office.Interop.Excel.Range>();
range.Setup(r => r.get_Value(1)).Returns("Something");
var classBeingTested = new MyClass(range.Object);
在单元测试的代码中,我使用Range如下:
public MyClass(Range range)
{
var value = range[1].ToString();
}
测试运行时会产生以下异常:
Error: Missing method 'instance object [My.Example.Implementation.MyClass] Microsoft.Office.Interop.Excel.Range::get__Default(object,object)' from class 'Castle.Proxies.RangeProxy'.
如何成功实施此模拟?我意识到将Excel Interop功能与https://stackoverflow.com/a/9486226/1548950这样的模式隔离是一种潜在的解决方案;但是,我很高兴能够从Microsoft.Office.Interop.Excel接口创建模拟。
编辑:有关此问题的更多详情
好的,这很奇怪。我已经创建了一个项目来测试jimmy_keen的建议。有用。但是,当我使用相同的建议来测试我遇到问题的项目时, 它抛出以下异常:Error: Missing method 'instance object [My.Example.Implementation.MyClass] Microsoft.Office.Interop.Excel.Range::get__Default(object,object)' from class 'Castle.Proxies.RangeProxy'.
由于jimmy_keen的建议在其他项目上运行良好,我开始怀疑我正在测试代码的项目有问题。所以,我创建了一个测试 详细说明问题的解决方案:http://www7.zippyshare.com/v/70834394/file.html
问题的根源似乎是项目包含另一个类(未进行单元测试),基本上包含以下代码:
using Microsoft.Office.Interop.Excel;
namespace Project
{
public class UnTestedClass
{
public UnTestedClass(Worksheet sheet)
{
var foo = sheet.Range["Description"].Column;
}
}
}
我不明白为什么会导致这个问题,因为我根本没有在单元测试中使用UnTestedClass。我错过了应该如何使用Moq,或者我偶然发现了一个错误?
答案 0 :(得分:5)
您的代码访问索引器,这就是您需要模拟的内容:
var range = new Mock<Microsoft.Office.Interop.Excel.Range>();
range.Setup(r => r[1, It.IsAny<object>()]).Returns("something");
请注意,Range
索引器实际上需要两个参数 - 因此调用It.IsAny<object>()
约束。