测试调用WCF服务的方法的单元测试

7
如何对调用WCF服务的业务层方法进行单元测试?
示例:
public void SendData(DataUnit dataUnit)
{

        //this is WCF call
        SomeServiceClient svc = new SomeServiceClient();

        svc.SomeMethod(dataUnit);

}

我能在我的单元测试项目中模拟SomeServiceClient吗?


我在这些情况下使用Moq来模拟服务接口。 - Yaur
1
这里的WCF没有什么特别之处(尽管客户端类实现接口的事实可能会对您有所帮助)。如果“SendData”需要调用某个类库方法,那么问题将完全相同。 - John Saunders
@Yakur:我该如何告诉 NUnit 框架,如果调用 SomeServiceClient,则使用此模拟对象。由于 SomeServiceClient 是在 BL 内部创建的,我不知道该如何传递它。 - Asdfg
2个回答

12

你的问题在于你将业务层和WCF服务紧耦合 - 你实际上在业务层中创建了服务客户端的新实例,这意味着现在无法调用SendData方法而不调用服务方法。

在这里最好的解决方案是将依赖注入到你的架构中。

简单来说,你所需要做的就是将服务类的一个实例传递到业务层中。这通常是在类构造时使用构造函数参数完成的。

public class BusinessClass
{
    private ISomeServiceClient _svc;

    public BusinessClass(ISomeServiceClient svc)
    {
        _svc = svc;
    }

    public void SendData(DataUnit dataUnit)
    {
       _svc.SomeMethod(dataUnit);
    }
}

请注意,上面的代码是一个设计模式,绝不依赖于任何像控制反转容器之类的框架。

如果您公司的政策是不使用这样的框架(这是一种疯狂的政策),您仍然可以在单元测试中手动注入服务的模拟实例。


无法在项目中使用依赖框架。公司政策。 :( - Asdfg
7
依赖注入作为一种架构模式,和使用DI框架或IOC容器是有区别的。 - David Hall

1

你应该将服务调用与业务层分开:

使用下面的演示,你列出的业务层方法现在应该是这样的:

public void SendData(IMyInterface myInterface, DataUnit dataUnit)
{

        myInterface.SomeMethod(dataUnit);

}

如果您想进行服务调用,请传递RealThing,如果您只想运行测试,请传递TestThing:

public interface IMyInterface
{
   void SomeMethod(DataUnit x);
}

public class RealThing : IMyInterface
{
   public void SomeMethod(DataUnit x)
   {
       SomeServiceClient svc = new SomeServiceClient();
       svc.SomeMethod(x);
   }
}

public class TestThing : IMyInterface
{
   public void SomeMethod(DataUnit x)
   {
       // do your test here
   }
}

这难道不会让我在两个地方都实现SomeMethod吗?如果我更改RealThing类中的某些内容,我可能需要回来更改TestThing的SomeMethod中的相同内容。我理解得对吗? - Asdfg

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接