Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mockito pattern for a Spring web service call

My class under test has this method

public SomeWebServiceResponse callDownstream(SomeWebServiceRequest request)  {
    return (SomeWebServiceResponse ) super.callService(request);
}

the super method is just a call to Spring WS to make the call - in simplified form

response = getWebServiceTemplate().marshalSendAndReceive(this.getBaseURL(), 
    request);
return response;

When I write a unit test it tried to make an actual web service call. I'm not clear how to mock this or rather what we should be mocking.

Should I be loading a sample response from filesystem and looking for some string in it - in that case I'm only testing file loading.

The actual call is in base class and I know we can't mock only that method. Any pointers?

like image 572
shinynewbike Avatar asked Apr 18 '13 11:04

shinynewbike


People also ask

How is Mockito used with spring?

Summary. Mocking in unit testing is extensively used in Enterprise Application Development with Spring. By using Mockito, you can replace the @Autowired components in the class you want to test with mock objects. You will be unit testing controllers by injecting mock services.

How do I mock a service in spring boot?

This is easily done by using Spring Boot's @MockBean annotation. The Spring Boot test support will then automatically create a Mockito mock of type SendMoneyUseCase and add it to the application context so that our controller can use it.

Can Mockito and PowerMock be used together?

Mockito allows us to create mock objects. Since static method belongs to the class, there is no way in Mockito to mock static methods. However, we can use PowerMock along with Mockito framework to mock static methods.


1 Answers

Spring does also provide facilities for mocking web service servers as well as requests from clients. The chapter 6.3 in the Spring WS manual shows how to do mocking.

The Spring WS mocking facility changes the behaviour of the Web Service Template, so you can call that method in the super-class - that method would then call the Spring Mock Service Server.

Here is a sample unit test with the Spring mock service server:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"classpath:spring-ws.xml"})
public class SetStatusFromSrsTemplateTest {
    @Autowired
    private WebServiceTemplate wsTemplate;

    @Before
    public void setUp() throws Exception {
        mockServer = MockWebServiceServer.createServer(wsTemplate);
    }

    @Test
    public void testCall() {
        SomeWebServiceRequest sampleRequest = new SomeWebServiceRequest();
        // add properties to the sampleRequest...
        Source expectedPayload = new ResourceSource(new ClassPathResource("exampleRequest.xml"));
        Source expectedResponse = new ResourceSource(new ClassPathResource("exampleResponse.xml"));
        mockServer.expect(payload(expectedPayload)).andRespond(withPayload(expectedResponse));
        instance.callDownStream(sampleRequest);
        mockServer.verify();
    }
}

The above example will make the mock service server expect exactly one request with the given payload and (if the payload received matches the expected payload) respond with the given response payload.

However, if you only want to verify that the method in the super-class is really called during the test and if you're not interested in the message exchange following that call, you should use Mockito.

If you'd like to use Mockito, I'd suggest the spy (see also Kamlesh's answer). E.g.

// Decorates this with the spy.
MyClass mySpy = spy(this);
// Change behaviour of callWebservice method to return specific response
doReturn(mockResponse).when(mySpy).callWebservice(any(SomeWebServiceRequest.class));
// invoke the method to be tested.
instance.callDownstream(request);
// verify that callWebService has been called
verify(mySpy, times(1)).callWebService(any(SomeWebServiceRequest.class));
like image 110
rowing-ghoul Avatar answered Oct 05 '22 12:10

rowing-ghoul