Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/293.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何使用Moq模拟Microsoft.Office.Interop.Excel.Range?_C#_.net_Unit Testing_Mocking_Moq - Fatal编程技术网

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

C# 如何使用Moq模拟Microsoft.Office.Interop.Excel.Range?,c#,.net,unit-testing,mocking,moq,C#,.net,Unit Testing,Mocking,Moq,我想模拟Microsoft.Office.Interop.Excel.Range(以及其他Microsoft.Office.Interop.Excel界面)来对我的应用程序进行单元测试。我在C#中使用了moq4.0.10827和.net4 在我的单元测试中,我尝试如下设置模拟的行为: var range = new Mock<Microsoft.Office.Interop.Excel.Range>(); range.Setup(r => r.g

我想模拟Microsoft.Office.Interop.Excel.Range(以及其他Microsoft.Office.Interop.Excel界面)来对我的应用程序进行单元测试。我在C#中使用了moq4.0.10827和.net4

在我的单元测试中,我尝试如下设置模拟的行为:

        var range = new Mock<Microsoft.Office.Interop.Excel.Range>();
        range.Setup(r => r.get_Value(1)).Returns("Something");

        var classBeingTested = new MyClass(range.Object);
    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'.
Error: Missing method 'instance object [My.Example.Implementation.MyClass] Microsoft.Office.Interop.Excel.Range::get__Default(object,object)' from class 'Castle.Proxies.RangeProxy'.
我如何才能成功地实现此模拟?我意识到,用一种模式隔离Excel互操作功能是一个潜在的解决方案;但是,如果能够从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'.
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的建议在其他项目上效果良好,我开始怀疑我正在测试代码的项目有问题。所以,我创建了一个测试 详细说明问题的解决方案:

问题的根源似乎是项目包含另一个类(未进行单元测试),其基本代码如下:

using Microsoft.Office.Interop.Excel;
namespace Project
{
    public class UnTestedClass
    {
        public UnTestedClass(Worksheet sheet)
        {
            var foo = sheet.Range["Description"].Column;
        }
    }
}

我不明白为什么会出现这个问题,因为我根本没有在单元测试中使用UnTestedClass。我是否在应该如何使用Moq的过程中遗漏了什么,或者我偶然发现了一个bug?

您的代码访问索引器,这就是您需要模拟的:

var range = new Mock<Microsoft.Office.Interop.Excel.Range>();
range.Setup(r => r[1, It.IsAny<object>()]).Returns("something");
var range=new Mock();
Setup(r=>r[1,It.IsAny()])。返回(“某物”);

请注意,
Range
索引器实际上需要两个参数-因此调用中的
It.IsAny()
约束。

+1这很奇怪,我猜它与COM对象有关。一旦我引用excel互操作,我就不能再引用我的Moq库。。。奇怪……在做了一些这方面的工作之后,我现在开始使用自己的自定义类和接口来隔离Microsoft.Office.Interop.Excel功能,而不是直接模仿Microsoft.Office.Interop.Excel.*。虽然这个问题的答案确实解决了眼前的问题,但嘲笑Microsoft.Office.Interop.Excel。*最终只是开始需要太多的安装工作才能使其变得有用。谢谢,我测试了这个问题,在某些情况下确实有效。然而,我正在进行的单元测试仍然顽固地拒绝工作。请看我上传到@LauriHarpf的测试解决方案:这很有趣。显然,这是编译器生成代码的“问题”。项目中编译器生成的
范围
类型接口具有额外属性(
)。我不知道这对Castle来说有什么问题。。。但它是COM。例如,如果您使用ILSpy检查程序集,您就会明白我的意思。编译器生成的代码不同(即使类是相同的),这一定是问题所在。请注意,如果存根
range.Setup(r=>r.Column),则返回(0)此测试也将通过。非常好,谢谢!间谍的尖端也是金色的;在我的真实项目中,除了列之外,我还看到了其他额外的属性。现在有“列”、“列”、“行”、“行”和“值”。这种行为可能会使我编写的任何单元测试变得非常脆弱,因为在任何时候,新属性都可能出现并破坏某些东西。。在任何情况下,通过使用您的提示和仔细模仿所有这些额外的特性,这是有效的,所以标记作为答案。谢谢你,先生!