Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to unit test a class that consumes a web service?

I have a class (lets call it A) that:

  • In the constructor takes a config and based on it, creates a stub of a web service and stores a reference to it in a private field.
  • Has a few methods that call web methods and some stuff inbetween.

I started to create a unit test that:

  • Creates an instance of a class A with a dummy configuration.
  • Through reflection it injects the mocked web service stub.

Although that web service has plenty of methods.

  • Should I mock them all (in every test, with different data)?
  • Or maybe I should create another layer that encapsulates only the web methods that are being used?
  • Or there is another approach?
like image 519
Janek Avatar asked Nov 23 '12 18:11

Janek


2 Answers

You should create a wrapper interface around your webservice, and make your class under test take a dependency on that interface, rather than directly on the webservice; you can then mock the interface. Only make that interface expose the methods of the webservice that you find interesting. This is known as a facade pattern, and is detailed here.

Without having a clue about what you're testing, aim for something like this:

public interface IWebserviceWrapper
{
    Whatever DoStuff(int something);
}

public class WebserviceWrapper : IWebserviceWrapper
{
    private WebService _theActualWebservice;

    public WebserviceWrapper(Webservice theService)
    {
        _theActualWebService = theService;
    }

    public Whatever DoStuff(int something)
    {
         return _theActualWebservice.DoSomething(something);
    }

}

Then your test would look like this (in this case, using MOQ)

public void Test_doing_something()
{
    Mock<IWebserviceWrapper> _serviceWrapperMock = new Mock<IWebserviceWrapper>();

    _serviceWrapperMock.SetUp(m => m.DoStuff(12345)).Returns(new Whatever());

    var classUnderTest = new ClassUnderTest(_serviceWrapperMock.Object);

    var result = classUnderTest.Dothings(12345);

    Assert.Whatever....

}
like image 89
Greg Smith Avatar answered Sep 30 '22 02:09

Greg Smith


Short answer Yes :). Long answer you should use some kind of mocking lib for example: http://code.google.com/p/mockito/ and in your unit test mock the WS stub and pass it to the tested class. That is the way of the force :)

like image 42
damiankolasa Avatar answered Sep 30 '22 02:09

damiankolasa