Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

unit test a method that calls wcf service

How do I unit test a Business Layer method that makes call to WCF service?

example:

public void SendData(DataUnit dataUnit)
{

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

        svc.SomeMethod(dataUnit);

}

Is there a way I can mock SomeServiceClient in my Unit test project?

like image 358
Asdfg Avatar asked May 26 '11 14:05

Asdfg


2 Answers

Your problem here is that you have tightly coupled your Business Layer to your WCF service - you actually create a new instance of the service client within the Business Layer, meaning that it is now impossible to call the SendData method without also calling the service methods.

The best solution here is to introduce dependency injection to your architecture.

At its simplest, all you do is pass an instance of your service class into your Business Layer. This is often done at class construction time using a constructor parameter.

public class BusinessClass
{
    private ISomeServiceClient _svc;

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

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

Note that the code above is a design pattern, with absolutely no reliance upon any framework like an Inversion of Control container.

If it is your company's policy not to use such frameworks (an insane policy by the way), you can still manually inject your mock instances of the service inside your unit tests.

like image 74
David Hall Avatar answered Oct 29 '22 16:10

David Hall


You should separate your service call from your business layer:

Using the demo below, your Business Layer method that you listed would now look like this:

public void SendData(IMyInterface myInterface, DataUnit dataUnit)
{

        myInterface.SomeMethod(dataUnit);

}

Pass in a RealThing if you want to do the service call, pass in a TestThing if you just want to run a test:

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
   }
}
like image 28
Nathan Avatar answered Oct 29 '22 16:10

Nathan