知識庫 / Spring / Spring Boot RSS 訂閱

Spring Web 服務集成測試 (@WebServiceServerTest)

Spring Boot,Testing
HongKong
4
12:02 PM · Dec 06 ,2025

1. 簡介

本文將介紹如何為使用 Spring Boot 構建的 SOAP Web 服務編寫集成測試。

我們已經知道如何為應用程序類編寫單元測試,並且我們已經在 Spring Boot 中的測試教程中涵蓋了通用的測試概念。因此,在這裏,我們將重點關注僅使用 <em @WebServiceServerTest</em>> 模塊測試 Web 服務層面的集成測試。

2. 測試 Spring Web 服務

在 Spring Web 服務中,端點是服務端服務實現的關鍵概念。 專門的 <em @Endpoint</em> 註解標記了被註解的類為一個 Web 服務端點。 重要的是,這些 端點負責接收 XML 請求消息、調用所需的業務邏輯,並以響應消息返回結果

2.1. Spring Web Services 測試支持

為了測試這些端點,我們可以通過傳遞所需的參數或模擬對象輕鬆創建單元測試。然而,主要缺點是這種方法並不能真正測試通過網絡發送的 XML 消息的內容。另一種方法是創建集成測試,這些測試確實可以驗證消息的 XML 內容。

Spring Web Services 2.0 引入了對這些端點的集成測試支持。核心類,該類提供此支持,是 MockWebServiceClient。它提供了一個流暢的 API,用於將 XML 消息發送到 Spring 應用程序上下文配置的適當端點。此外,我們還可以設置響應期望、驗證響應 XML 以及對我們的端點執行完整的集成測試。

但是,這需要啓動整個應用程序上下文,從而導致測試執行速度變慢。這在創建針對特定 Web 服務端點的快速且隔離的測試時尤其不理想。

2.2. Spring Boot <em @WebServiceServerTest

Spring Boot 2.6 通過使用 <em @WebServiceServerTest 註解擴展了 Web 服務測試支持。

我們可以使用它來執行 僅關注 Web 服務層,而無需加載整個應用程序上下文的測試。換句話説,我們可以創建一個只包含必需的 <em @Endpoint Bean 的測試片段,並使用 <em @MockBean 模擬任何依賴項。

這與 Spring Boot 提供的便捷測試片段註解非常相似,例如 <em @WebMvcTest、<em @DataJpaTest 以及其他各種註解。

3. 設置示例項目

This section describes how to set up the example project. You will need to clone the repository and install the necessary dependencies.

Prerequisites

  • Git
  • Node.js (v16 or higher)
  • npm or yarn

Installation

  1. Clone the repository:

    git clone [repository URL]
    
  2. Navigate to the project directory:

    cd [project directory name]
    
  3. Install the dependencies:

    npm install  # or yarn install
    
  4. Verify the installation:

    npm run build # or yarn build
    

3.1. 依賴項

鑑於我們之前已經對 Spring Boot Web 服務項目進行了詳細説明,這裏我們只需添加用於我們項目所需的額外測試範圍的 <a href="https://mvnrepository.com/artifact/org.springframework.ws/spring-ws-test">spring-ws-test</a> 依賴項:

<dependency>
    <groupId>org.springframework.ws</groupId>
    <artifactId>spring-ws-test</artifactId>
    <version>4.0.10</version>
    <scope>test</scope>
</dependency>

3.2. 示例 Web 服務

接下來,讓我們創建一個簡單的服務,用於返回指定的產品 ID 的產品數據:

@Endpoint
public class ProductEndpoint {

    @Autowired
    private ProductRepository productRepository;

    @ResponsePayload
    public GetProductResponse getProduct(@RequestPayload GetProductRequest request) {
        GetProductResponse response = new GetProductResponse();
        response.setProduct(productRepository.findProduct(request.getId()));
        return response;
    }
}

在這裏,我們對 ProductEndpoint 組件進行了標註,使用了 @Endpoint 註解,使其能夠處理相應的 XML 請求。

getProduct 方法接收請求對象,並從一個倉庫中獲取產品數據,然後再返回響應。 倉庫的細節在這裏並不重要。 在我們的情況下,我們可以使用一個簡單的內存實現,以保持應用程序的簡潔,並專注於我們的測試策略。

4. 端點測試

最後,我們可以創建測試切片並驗證 XML 消息在 Web 服務層中的正確處理:

@WebServiceServerTest
class ProductEndpointIntegrationTest {

    @Autowired
    private MockWebServiceClient client;

    @MockBean
    private ProductRepository productRepository;

    @Test
    void givenXmlRequest_whenServiceInvoked_thenValidResponse() throws IOException {
        Product product = createProduct();
        when(productRepository.findProduct("1")).thenReturn(product);

        StringSource request = new StringSource(
          "<bd:getProductRequest xmlns:bd='http://baeldung.com/spring-boot-web-service'>" + 
            "<bd:id>1</bd:id>" + 
          "</bd:getProductRequest>"
        );
        
        StringSource expectedResponse = new StringSource(
          "<bd:getProductResponse xmlns:bd='http://baeldung.com/spring-boot-web-service'>" + 
            "<bd:product>" + 
              "<bd:id>1</bd:id>" + 
              "<bd:name>Product 1</bd:name>" + 
            "</bd:product>" + 
          "</bd:getProductResponse>"
        );

        client.sendRequest(withPayload(request))
          .andExpect(noFault())
          .andExpect(validPayload(new ClassPathResource("webservice/products.xsd")))
          .andExpect(payload(expectedResponse))
          .andExpect(xpath("/bd:getProductResponse/bd:product[1]/bd:name", NAMESPACE_MAPPING)
            .evaluatesTo("Product 1"));
    }
}

在這裏,我們僅配置了帶有 @Endpoint 註解的 Bean,用於我們的集成測試。換句話説,這個測試切片創建一個簡化的應用程序上下文。這有助於我們構建針對性強、快速的集成測試,而無需重複加載整個應用程序上下文所帶來的性能懲罰。

重要的是,這個註解也配置了一個 MockWebServiceClient,以及其他相關的自動配置。因此,我們可以將這個客户端連接到我們的測試中,並使用它來發送 getProductRequest XML 請求,然後跟隨各種 Fluent 期望。

這些期望驗證響應 XML 與給定的 XSD 模式進行驗證,並且與預期的 XML 響應匹配。我們還可以使用 XPath 表達式來評估和比較響應 XML 中的各種值。

4.1. 端點協作者

在我們的示例中,我們使用了 <em @MockBean</em> 來模擬 <em ProductEndpoint</em>> 中所需的倉庫。缺少此模擬,應用程序上下文無法啓動,因為全自動配置已禁用。換句話説,<strong>測試框架在執行測試之前不會配置任何<em>@Component</em>、<em>@Service</em> 或 <em>@Repository</em> 類型的 Bean</strong>

但是,如果我們確實需要使用實際的協作者而不是模擬,則可以使用 <em @Import</em> 聲明它們。Spring 將查找這些類,然後將它們連接到端點,如需要。

4.2. 加載整個上下文

正如之前所述,<em@WebServiceServerTest</em>> 將不會加載整個應用程序上下文。如果確實需要為測試加載整個應用程序上下文,那麼我們應該考慮使用 <em@SpringBootTest</em>><em@AutoConfigureMockWebServiceClient</em> 結合使用。 這樣,我們就可以像之前一樣,使用該客户端發送請求並驗證響應。

5. 結論

在本文中,我們探討了 Spring Boot 中引入的 <em @WebServiceServerTest</em> 註解。

最初,我們討論了在 Web 服務應用程序中 Spring Boot 的測試支持。隨後,我們看到了如何使用此註解創建 Web 服務層面的測試模塊,從而構建快速且聚焦的集成測試。

user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.