繁体   English   中英

Spring Boot:模拟 SOAP Web 服务

[英]Spring Boot: Mocking SOAP Web Service

我想知道在 Spring Boot 中模拟 SOAP Web 服务的最佳实践是为了运行集成测试。 我在 spring 网站上能找到的只有https://spring.io/guides/gs/sumption-web-service/ 我们是否必须为像模拟依赖这样简单的事情创建模式/wsdl?

要模拟 REST 服务,我们所要做的就是将 @RestController 注释添加到我们的模拟服务中以使其启动。 我正在寻找一种轻量级的解决方案。

注意:我目前使用 REST Assured 进行集成测试。

谢谢!

我使用 WireMock 来模拟外部 SOAP 服务器依赖项。

测试类本身使用@SpringBootTest注释来确保我有与真实环境相似的上下文。

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();
}

RawMessage.xml的内容是消息响应。 在我的情况下,它是一个多部分消息(简化):

------=_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--

这种设置使我能够尽可能地模拟真实通话。

试试这个模板:

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();
    }
}

最简单的方法是模拟负责与 Soap Web Service 进行集成的 bean。

例如,如果您有一个SoapWebService使用 Soap 与另一个 Web 服务进行此通信,则可以在测试中使用@MockBean注释并模拟返回。 示例:

@SpringBootTest
@WebAppConfiguration
@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_CLASS)
@RunWith(SpringRunner.class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class YourControllerIT {

    @MockBean
    private SoapWebService soapWebService ;

    @Before
    public void setup() {
        when(soapWebService.soapCall(
                any(), anyLong())).thenReturn("mockedInformation");
    }

    @Test
    public void addPerson() {
         MvcResult mvcResult = mockMvc.perform(post("/api/persons")
                .accept("application/json")
                .header("Content-Type", "application/json")
                .content(jsonContent))
                .andExpect(status().isCreated())
                .andReturn();
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM