Search code examples
javaweb-servicesspring-wsspring-test

Testing Web Service client with MockWebServiceServer: sequence of requests


I need to test a Web Service client with spring-ws-test 3.0.1.RELEASE. The sequence of requests is been performed according to the business logic is as follows:

  1. Ask the router endpoint about particular store's URL;
  2. Hit the particular store's URL to get employee's permission to do some staff;
  3. Ask the router endpoint about the same store's URL (there are concrete reasons to repeat the request);
  4. Hit almost always the same store's URL to do some staff on behalf of employee.

Another words, my test hits a mocked Web Service server four times. Two times it hits the router endpoint (1, 3) with the same payload and two times it hits the particular store's URL (2, 4), but with different payload.

What I wonder is how should I code mocked Web Service server's expectations to withstand such a payload? Considering that:

@RunWith(SpringRunner.class)
@SpringBootTest
public class SomeClientTest {
    @Autowired
    private SomeClient someClient;

    private MockWebServiceServer mockWebServiceServer;

    @Before
    public void setUp() {
        mockWebServiceServer = MockWebServiceServer.createServer(someClient);
    }

    @Test
    public void fourHitsMethodTest() {     
        //mocks the 1st and the 3rd responses
        mockWebServiceServer
        .expect(payload(getUrlRequest()))
        .andRespond(withPayload(getUrlResponse()));
        //mocks the 2nd response
        mockWebServiceServer
        .expect(payload(getEmployeesPermissionRequest()))
        .andRespond(withPayload(getEmployeesPermissionResponse()));
        //mocks the 4th response
        mockWebServiceServer
        .expect(payload(doSomeStaffRequest()))
        .andRespond(withPayload(doSomeStaffResponse()));
        //those 4 hits are been performed in fourHitsMethod()
        assertNotNull(someClient.fourHitsMethod("foo", "bar"));
        mockWebServiceServer.verify();
    }
}

Fails with java.lang.AssertionError: No further connections expected.


Solution

  • The answer is partly revealed by the question. Since I have 4 hits, I have to declare 4 expectations respectably. And in the order I expect them to be called. Under the hood MockWebServiceServer deletes every expectation once it has been hit. The follows works fine:

    @RunWith(SpringRunner.class)
    @SpringBootTest
    public class SomeClientTest {
        @Autowired
        private SomeClient someClient;
    
        private MockWebServiceServer mockWebServiceServer;
    
        @Before
        public void setUp() {
            mockWebServiceServer = MockWebServiceServer.createServer(someClient);
        }
    
        @Test
        public void fourHitsMethodTest() {     
            //mocks only the 1st, but not the 3rd response
            mockWebServiceServer
            .expect(payload(getUrlRequest()))
            .andRespond(withPayload(getUrlResponse()));
            //mocks the 2nd response
            mockWebServiceServer
            .expect(payload(getEmployeesPermissionRequest()))
            .andRespond(withPayload(getEmployeesPermissionResponse()));
            //mocks the 3rd response
            mockWebServiceServer
            .expect(payload(getUrlRequest()))
            .andRespond(withPayload(getUrlResponse()));
            //mocks the 4th response
            mockWebServiceServer
            .expect(payload(doSomeStaffRequest()))
            .andRespond(withPayload(doSomeStaffResponse()));
            //those 4 hits are been performed in fourHitsMethod()
            assertNotNull(someClient.fourHitsMethod("foo", "bar"));
            mockWebServiceServer.verify();
        }
    }
    

    Note the difference in expectations comparing to the question. Here I have 4 expectations against 3 in the question.

    Not quite obvious for me referencing https://docs.spring.io/spring-ws/docs/current/api/org/springframework/ws/test/client/MockWebServiceServer.html