使用 RestAssured 發送 MultipartFile 請求

REST,Testing
Remote
0
04:36 AM · Dec 01 ,2025

1. 概述

在本教程中,我們將使用 RestAssured 庫向服務器發送多部分請求。這對於測試 Spring 中的多部分控制器或針對已部署服務器編寫集成測試非常有用。

2. 什麼是多部分請求?

在多部分請求中,數據被分成多個部分。 每個部分都有一個名稱和一組自己的標頭,指示其包含的數據類型。 數據和每個部分之間的邊界進行編碼。

3. 設置

讓我們設置我們使用的庫。

3.1. RestAssured 測試庫

RestAssured 是一個基於 Java 的庫,它提供了一種特定於域的語言,用於編寫 RESTful Web 服務自動化測試。

讓我們先將 RestAssured 庫添加到我們的 pom.xml 中:

<dependency>
    <groupId>io.rest-assured</groupId>
    <artifactId>rest-assured</artifactId>
    <version>5.5.0</version>
    <scope>test</scope>
</dependency>

3.2. 設置 Wiremock 服務器

我們將使用 RestAssured 發送多部分請求。 在實際情況下,這些請求將到達我們想要測試的目標服務器。 為了我們的示例,我們將使用 Wiremock 來代替真實的服務器。

WireMock 是一個開源庫,用於模擬 Web 服務。 它允許我們創建樁,用於測試客户端與服務器之間的交互。

讓我們將 Wiremock 庫添加到我們的 pom.xml 中:

<dependency>
    <groupId>org.wiremock</groupId>
    <artifactId>wiremock-standalone</artifactId>
    <version>3.9.1</version>
    <scope>test</scope>
</dependency>

現在,我們可以配置 Wiremock 服務器在我們的 JUnit 測試中。 我們將使其在每個測試方法之前啓動,並在測試方法之後停止:

private WireMockServer wireMockServer;

@BeforeEach
void startServer() {
    wireMockServer = new WireMockServer();
    wireMockServer.start();
}

@AfterEach
void stopServer() {
    wireMockServer.stop();
}

4. 發送文件與 RestAssured

我們將快速設置我們的模擬服務器,然後轉向編寫 RestAssured 測試。

4.1. 文件處理

讓我們創建一個文件 baeldung.txt,位於 test/resources 目錄中。 為了準備文件發送,讓我們編寫兩個實用方法:

  • 給定文件名,getFile() 檢索相應的 File 對象
  • getFileContent() 讀取文件內容

以下是我們的方法:

File getFile(String fileName) throws IOException {
    return new ClassPathResource(fileName).getFile();
}

String getFileContent(String fileName) throws IOException {
    return new String(Files.readAllBytes(Paths.get(getFile(fileName).getPath())));
}

4.2. 模擬服務器創建

我們將文件 baeldung.txt 發送到 URL /upload。 我們將 file 設置為 multipart 請求中文件的控制名稱。

首先,我們將創建一個期望接收此類請求的模擬服務器。 此外,我們還將檢查 Content-Type 標頭是否為 multipart/form-data。 當請求滿足所有這些條件時,我們將返回一個 200 響應狀態:

stubFor(post(urlEqualTo("/upload"))
  .withHeader("Content-Type", containing("multipart/form-data"))
  .withRequestBody(containing("file"))
  .withRequestBody(containing(getFileContent("baeldung.txt")))
  .willReturn(aResponse().withStatus(200)));

4.3. RestAssured 測試請求

現在是時候專注於我們將發送到服務器的 multipart 請求。 使用 RestAssured,請求規範遵循給-定-當-然範式。

首先,我們將使用 multipart() 方法添加 multipart。 讓我們看看它的參數:

  • file,與請求中文件關聯的控制名稱
  • 文件內容

然後,我們將使用 post() 方法發出 HTTP POST 請求。 它的參數是 /upload 目標 URL。 最後,我們將使用 statusCode() 方法設置預期的響應狀態:

given()
  .multiPart("file", getFile("/baeldung.txt"))
  .when()
  .post("/upload")
  .then()
  .statusCode(200);

現在我們可以將此請求針對之前的模擬服務器進行測試:狀態碼正確!

通過反覆調用 multipart() 方法,我們可以向測試請求添加更多文件。 例如,我們可以添加一個新文件 helloworld.txt,並將相應的部分在請求中命名為 helloworld

given() 
  .multiPart("file", getFile("/baeldung.txt"))
  .multiPart("helloworld", getFile("/helloworld.txt"))
  .when() 
  .post("/upload") 
  .then() 
  .statusCode(200);

5. 構建我們的多部分規範

有時,我們希望在請求中提供更詳細的多部分內容。讓我們看看如何做到這一點。

5.1. 模擬服務器更新

讓我們快速更新我們的 Wiremock 模擬服務器。 這一次,我們將期望請求包含一個名為 file的多部分內容。文件名將是 file.txt。請求的 Content-Type 標頭將是 text/plain,並且主體將包含 File content

我們將使用 MultipartValuePatternBuilder 來完成我們的模擬服務器規範:

MultipartValuePatternBuilder multipartValuePatternBuilder = aMultipart()
  .withName("file")
  .withHeader("Content-Disposition", containing("file.txt"))
  .withBody(equalTo("File content"))
  .withHeader("Content-Type", containing("text/plain"));

stubFor(post(urlEqualTo("/upload"))
  .withMultipartRequestBody(multipartValuePatternBuilder)
  .willReturn(aResponse().withStatus(200)));

5.2. 多部分規範

現在讓我們轉向編寫測試請求。 感謝 RestAssured 庫中的 MultipartSpecification 類,我們可以將控制名稱設置為名稱、MIME 類型、字符集和文件內容。控制名稱在服務器端標識部分,而文件名由發送方設置。

因此,我們將構建一個簡單的示例,其中:

  • 該部分將被命名為 file
  • 給文件的名稱是 file.txt
  • 文件的 MIME 類型是 text/plain

因此,請求的 Content-Typetext/plain,而不是 multipart/form-data。儘管如此,這仍然是一個多部分請求,因為內容已編碼在部分中。 此外,我們不需要使用磁盤上的現有文件。 為了展示這一點,我們將從一個 String 生成內容:

MultiPartSpecification multiPartSpecification = new MultiPartSpecBuilder("File content".getBytes())
  .fileName("file.txt")
  .controlName("file")
  .mimeType("text/plain")
  .build();

現在我們可以使用 multipart() 方法直接使用 MultipartSpecification 作為參數更新我們的 RestAssured 請求規範:

given()
  .multiPart(multiPartSpecification)
  .when()
  .post("/upload")
  .then()
  .statusCode(200);

現在我們知道如何為我們的 RestAssured 多部分請求帶來更大的粒度。

6. 結論

在本文中,我們使用 RestAssured 向一個模擬服務器發送多部分請求。

我們看到了如何僅通過內容發送文件並控制名稱,然後切換到構建更復雜的組成部分。

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

發佈 評論

Some HTML is okay.