如何使用非虚函数对单元测试模拟对象

时间:2010-02-02 20:37:52

标签: c# unit-testing mocking

我有一个使用wsdl.exe工具生成的C#类,如下所示:

public partial class SoapApi : System.Web.Services.Protocols.SoapHttpClientProtocol
{
    public SOAPTypeEnum AskServerQuestion()
    {
        object[] results = return this.Invoke("AskServerQuestion");
        return (SOAPTypeEnum) results[0];
    }
}

我有一些瘦的包装代码,可以跟踪结果等。是否可以使用任何对象模拟框架来创建一个假的SoapApi类,并为每个对瘦包装器的调用返回可预测的结果功能

我无法将AskServerQuestion()函数设为虚拟,因为它是由wsdl.exe工具自动生成的。

3 个答案:

答案 0 :(得分:4)

我完成此操作的方法是注入一个ISoapApi,其中ISoapApi接口模仿自动生成的SOAP API。

对于你的情况:

public interface ISoapApi
{
    SOAPTypeEnum AskServerQuestion ();
}

然后,利用生成的SoapApi类是部分的这一事实,并将其添加到另一个文件中:

public partial class SoapApi : ISoapApi
{
}

然后,消费者应该采用可以被任何模拟框架模拟的ISoapApi依赖。

当然,一个缺点是,当SOAP api发生变化时,您还需要更新接口定义。

答案 1 :(得分:1)

该类是部分的,因此您可以使类在您编写的部分类部分中实现接口。 然后,您可以模拟界面。

答案 2 :(得分:1)

我制定了一种技术,适用于类非偏的情况。假设这是原始类:

// Generated class, can't modify.
public class SomeClass
{
    // Non-virtual function, can't mock.
    public void SomeFunc() { //... }
}

首先,从该类中提取接口:

public interface ISomeClass
{
    void SomeFunc();
}

现在创建一个继承上述两个类的新类:

public SomeClass2 : SomeClass, ISomeClass
{
    // The body of this class is empty.
}

现在,您可以在程序中使用SomeClass2。它的行为与SomeClass相同。你可以模仿ISomeClass