Webserviceioexception When Testing a Web Service Client Using Mockwebserviceserver

I'm trying to write an integration test and part of that test requires mocking a REST call and also a SOAP call. The REST part works fine, I'm able to mock that. The SOAP call is proving difficult to mock. I get an WebServiceIOException.

Caused by: org.springframework.ws.client.WebServiceIOException: I/O error: Connection refused: connect; nested exception is java.net.ConnectException: Connection refused: connect
    at org.springframework.ws.client.core.WebServiceTemplate.sendAndReceive(WebServiceTemplate.java:561)
    at org.springframework.ws.client.core.WebServiceTemplate.marshalSendAndReceive(WebServiceTemplate.java:390)
    at org.springframework.ws.client.core.WebServiceTemplate.marshalSendAndReceive(WebServiceTemplate.java:378)
    at ca.nbc.payment.pmt_commons_mcp_connector.service.OdsPreferencesConnector.getPreferences(OdsPreferencesConnector.java:18)
    at ca.nbc.payment.pmt_commons_mcp_connector.service.McpConnectorMessageService.processGetCustomerMessage(McpConnectorMessageService.java:46)
    at ca.nbc.payment.pmt_commons_mcp_connector.stream.McpConnectorStreamListener.handleCustomerManagementMessageRetrieve(McpConnectorStreamListener.java:29)
    at (Native Method)
    at (NativeMethodAccessorImpl.java:62)
    at (DelegatingMethodAccessorImpl.java:43)
    at (Method.java:566)
    at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:171)
    at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:120)
    at org.springframework.cloud.stream.binding.StreamListenerMessageHandler.handleRequestMessage(StreamListenerMessageHandler.java:55)

Here is my client class, the class that extends WebServiceGatewaySupport

public class OdsPreferencesConnector extends WebServiceGatewaySupport {

  @Value("${ods.url}")
  private String odsUrl;

  public String getPreferences(String memberIdNo) {
    GetPreferencesResponse getPreferencesResponse = (GetPreferencesResponse) getTemplate().marshalSendAndReceive(odsUrl, getGetPreferencesRequest(memberIdNo));

    if (!getPreferencesResponse.getServiceResponse().getPreferenceList().getPreference().isEmpty()) {
      return getPreferencesResponse.getServiceResponse().getPreferenceList().getPreference().get(0).getPrefValue();
    }

    return null;
  }

  private WebServiceTemplate getTemplate() {
    WebServiceTemplate webServiceTemplate = new WebServiceTemplate();

    Jaxb2Marshaller jaxb2Marshaller = new Jaxb2Marshaller();
    jaxb2Marshaller.setClassesToBeBound(GetPreferencesRequest.class, GetPreferencesResponse.class);
    webServiceTemplate.setMarshaller(jaxb2Marshaller);
    webServiceTemplate.setUnmarshaller(jaxb2Marshaller);

    return webServiceTemplate;
  }

  private GetPreferencesRequest getGetPreferencesRequest(String memberIdNo) {
    GetPreferencesRequest getPreferencesRequest = new GetPreferencesRequest();

    getPreferencesRequest.setServiceRequest(new GetPreferencesRequestType());
    getPreferencesRequest.getServiceRequest().setPartyNumber(new PartyNumberType());
    getPreferencesRequest.getServiceRequest().getPartyNumber().setMemberIdNo(memberIdNo);

    return getPreferencesRequest;
  }

}

Here is my test class

@SpringBootTest
@ActiveProfiles("integration-tests")
class IntegrationTest {

  @Autowired
  private ObjectMapper objectMapper;

  @Autowired
  private MessageCollector messageCollector;

  @Autowired
  private McpConnectorStream mcpConnectorStream;

  @Autowired
  private static OdsPreferencesConnector odsPreferencesConnector;

  private static MockWebServiceServer mockServer;

  private static WireMockServer wireMockServer;

  @BeforeAll
  public static void setup() {
    wireMockServer = new WireMockServer(options().bindAddress("127.0.0.1").port(14000));
    wireMockServer.start();

    odsPreferencesConnector = new OdsPreferencesConnector();

    ReflectionTestUtils.setField(odsPreferencesConnector, "odsUrl", "");

    mockServer = MockWebServiceServer.createServer(odsPreferencesConnector);
  }

  @AfterAll
  public static void afterAll() {
    wireMockServer.stop();
  }

  @Test
  void handleCustomerManagementMessageGet() throws Exception {
    PaymentCommonsCustomer receivedMessage = TestObjectBuilder.createPaymentCommonsCustomerMessage();
    GetIndividualBaseResponse getIndividualBaseResponse = TestObjectBuilder.createIndividualBaseResponse();

    // Mock MCP REST call
    wireMockServer.stubFor(WireMock.get("/individuals/" + receivedMessage.getBncId() + "/base")
        .willReturn(aResponse()
            .withHeader("Content-Type", "application/json")
            .withBody(objectMapper.writeValueAsString(getIndividualBaseResponse))));

    // Mock ODS SOAP call
    Source requestPayload = new StringSource(TestObjectBuilder.createGetPreferencesRequestXML());
    Source responsePayload = new StringSource(TestObjectBuilder.createGetPreferencesResponseXML());
    mockServer.expect(payload(requestPayload)).andRespond(withPayload(responsePayload));

    sendMessage(receivedMessage, StreamAction.ACTION_GET);

    Message<String> sentMessageJson = (Message<String>) messageCollector.forChannel(mcpConnectorStream.outboundCustomerApi()).poll();
    assertNotNull(sentMessageJson);

    PaymentCommonsCustomer sentMessage = objectMapper.readValue(sentMessageJson.getPayload(), PaymentCommonsCustomer.class);

    assertEquals(receivedMessage.getMessageId(), sentMessage.getMessageId());
    assertEquals(receivedMessage.getTransactionDate(), sentMessage.getTransactionDate());
    assertEquals(receivedMessage.getLastPublishedDate(), sentMessage.getLastPublishedDate());
  }

  private void sendMessage(PaymentCommonsCustomer message, String action) throws Exception {
    mcpConnectorStream.inboundMcpConnector().send(MessageBuilder.withPayload(objectMapper.writeValueAsString(message)).setHeader("action", action).build());
  }

}

If the SOAP web service is up, then my unit test works fine. Is there something I'm missing or doing wrong? I'm using Java 11 and JUnit 5.

1 Answer

I had a similar issue recently. The problem is your WebServiceTemplate, you are creating a new instance each time you call your service.

Instead of that, try to either inject a WebServiceTemplate or use the one WebServiceGatewaySupport.getWebServiceTemplate() provides by default and do not manipulate anything from the service template when you call your service.

One thing that MockWebServiceServer.createServer(client) does, it's to take your service template and set a MockWebServiceMessageSender as a message sender which is the one you need to avoid the actual http call, in your code the mock is never been called because the creation of a new service template instance everytime. Finally, you won't need the WireMockServer

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Elena Rostova

Elena Rostova

Lead Health, Wellness & Medical Journalist

Elena Rostova holds a Master's degree in Public Health Journalism. She covers groundbreaking medical research, holistic wellness trends, mental health awareness, and nutritional science.

Share this article
Twitter Facebook Pinterest