使用Spring WS客户端处理SoapFault - WebServiceGatewaySupport和WebServiceTemplate

时间:2017-03-28 19:57:54

标签: integration-testing soap-client spring-ws

我正在尝试使用WebServiceGatewaySupport编写Spring WS客户端。我设法测试客户端是否有成功的请求和响应。现在我想编写肥皂故障的测试用例。

public class MyClient extends WebServiceGatewaySupport {
     public ServiceResponse method(ServiceRequest serviceRequest) {
          return (ServiceResponse) getWebServiceTemplate().marshalSendAndReceive(serviceRequest);
}

@ActiveProfiles("test")
@RunWith(SpringRunner.class)
@SpringBootTest(classes = SpringTestConfig.class)
@DirtiesContext 
public class MyClientTest {
   @Autowired
   private MyClient myClient;

   private MockWebServiceServer mockServer;

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

我的问题是如何在模拟服务器中存根soap故障响应,以便我的自定义FaultMessageResolver能够解组soap故障?

我尝试了以下几项,但没有任何效果。

 // responsePayload being SoapFault wrapped in SoapEnvelope
 mockServer.expect(payload(requestPayload))
            .andRespond(withSoapEnvelope(responsePayload));

 // tried to build error message
 mockServer.expect(payload(requestPayload))
            .andRespond(withError("soap fault string"));

 // tried with Exception
 mockServer.expect(payload(requestPayload))
            .andRespond(withException(new RuntimeException));

感谢任何帮助。谢谢!

跟进:

好吧,withSoapEnvelope(有效负载)我设法让控制器转到我的自定义MySoapFaultMessageResolver。

public class MyCustomSoapFaultMessageResolver implements FaultMessageResolver     {

private Jaxb2Marshaller jaxb2Marshaller;

@Override
public void resolveFault(WebServiceMessage message) throws IOException {

    if (message instanceof SoapMessage) {
        SoapMessage soapMessage = (SoapMessage) message;

        SoapFaultDetailElement soapFaultDetailElement = (SoapFaultDetailElement) soapMessage.getSoapBody()
            .getFault()
            .getFaultDetail()
            .getDetailEntries()
            .next();
        Source source = soapFaultDetailElement.getSource();
        jaxb2Marshaller = new Jaxb2Marshaller();
        jaxb2Marshaller.setContextPath("com.company.project.schema");
        Object object = jaxb2Marshaller.unmarshal(source);
        if (object instanceof CustomerAlreadyExistsFault) {
            throw new CustomerAlreadyExistsException(soapMessage);
        }
    }
  }
} 

但是说真的!我不得不解组每条消息并检查它的实例。作为一个客户端,我应该彻底了解服务的所有可能的例外,并创建自定义运行时异常并从解析器中抛出它。仍然在最后,它被捕获在WebServiceTemplate中,并作为运行时异常重新抛出。

1 个答案:

答案 0 :(得分:0)

你可以尝试这样的事情:

@Test
public void yourTestMethod() // with no throw here
{
    Source requestPayload = new StringSource("<your request>");
    String errorMessage = "Your error message from WS";

    mockWebServiceServer
        .expect(payload(requestPayload))
        .andRespond(withError(errorMessage));

    YourRequestClass request = new YourRequestClass();
    // TODO: set request properties...

    try {
        yourClient.callMethod(request);    
    } 
    catch (Exception e) {
        assertThat(e.getMessage()).isEqualTo(errorMessage);
    }
    mockWebServiceServer.verify();
}

在这部分代码中, mockWebServiceServer 表示 MockWebServiceServer 类的实例。