如何使用Moq模拟Microsoft.Office.Interop.Excel.Range?

时间:2012-07-24 14:28:04

标签: c# .net unit-testing mocking moq

我想模拟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,或者我偶然发现了一个错误?

1 个答案:

答案 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>()约束。