Spring Boot: Mocking SOAP Web Service

10,807

Solution 1

I used WireMock to mock an external SOAP server dependency.

The test class itself used the @SpringBootTest annotation to make sure I have a similar context to the real environment.

private WireMockServer wireMockServer = new WireMockServer(wireMockConfig().port(8089));

@Autowired
SoapClient soapClient;

@Test
@DisplayName("Retrieve SOAP message")
void retrieveMessage() {
    wireMockServer.start();
    WireMock.configureFor("localhost", 8089);
    WireMock.reset();
    stubFor(post(urlEqualTo("/ECPEndpointService"))
            .willReturn(
                    aResponse()
                            .withStatus(200)
                            .withHeader("Content-Type",
                                    "Multipart/Related; boundary=\"----=_Part_112_400566523.1602581633780\"; type=\"application/xop+xml\"; start-info=\"application/soap+xml\"")
                            .withBodyFile("RawMessage.xml")
            )
    );
    soapClient.retrieveActivations();
    wireMockServer.stop();
}

The content of the RawMessage.xml is the message response. In my case it was a multipart message (simplified):

------=_Part_112_400566523.1602581633780
Content-Type: application/xop+xml; charset=utf-8; type="application/soap+xml"

<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope">
    <env:Header/>
    <env:Body>
        <ns5:ReceiveMessageResponse xmlns:ns3="http://mades.entsoe.eu/" xmlns:ns4="http://mades.entsoe.eu/2/" xmlns:ns5="http://ecp.entso-e.eu/" xmlns:ns6="http://ecp.entsoe.eu/endpoint">
        <receivedMessage>
            ...
        </receivedMessage>
        <remainingMessagesCount>0</remainingMessagesCount>
        </ns5:ReceiveMessageResponse>
    </env:Body>
</env:Envelope>
------=_Part_112_400566523.1602581633780
Content-Type: application/octet-stream
Content-ID: <7a2f354f-dc52-406b-a4b1-9d89aa29cb2d@null>
Content-Transfer-Encoding: binary

<?xml version="1.0" encoding="UTF-8"?>
<edx:Message
    xmlns:edx="http://edx.entsoe.eu/internal/messaging/message"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <edxMetadata>
        ...
    </edxMetadata>
    <content v="PEFjdGl2YXRpb25"/>

</edx:Message>
------=_Part_112_400566523.1602581633780--

This setup allowed me to simulate a real call as much as possible.

Solution 2

Try this template:

import org.junit.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.xml.transform.StringSource;
import org.springframework.ws.test.client.MockWebServiceServer;
import static org.springframework.ws.test.client.RequestMatchers.*;
import static org.springframework.ws.test.client.ResponseCreators.*;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("applicationContext.xml")
public class MyWebServiceClientIntegrationTest {

    // MyWebServiceClient extends WebServiceGatewaySupport, and is configured in applicationContext.xml
    @Autowired
    private MyWebServiceClient client;

    private MockWebServiceServer mockServer;

    @Before
    public void createServer() throws Exception {
        mockServer = MockWebServiceServer.createServer(client);
    }
 
    @Test
    public void getCustomerCount() throws Exception {
        Source expectedRequestPayload = new StringSource("some expected xml");
        Source responsePayload = new StringSource("some payload xml");

        mockServer.expect(payload(expectedRequestPayload)).andRespond(withPayload(responsePayload));

        // client.getCustomerCount() uses the WebServiceTemplate
        int customerCount = client.getCustomerCount();
        assertEquals(10, response.getCustomerCount());

        mockServer.verify();
    }
}

Share:
10,807
Jason King
Author by

Jason King

Updated on June 04, 2022

Comments

  • Jason King
    Jason King almost 2 years

    I was wondering what the best practise to mock SOAP web services in spring boot is in order to run integration tests. All I could find on the spring website was https://spring.io/guides/gs/consuming-web-service/. Do we have to create a schema/wsdl for something as simple as mocking a dependency?

    To mock a REST service, all we have to do is add the @RestController annotation to our mock service for it to boot. I was looking for a solution as lightweight.

    Note: I'm currently using REST Assured for integration testing.

    Thanks!

  • DaviesTobi alex
    DaviesTobi alex about 3 years
    I tried this and got a SaxException : content not allowed in trailing section.