使用 RestAssured 發送 MultipartFile 請求
一、概述
在本教程中,我們將使用 RestAssured 庫向服務器發送多部分請求。這對於在 Spring 中測試多部分控制器或針對已部署的服務器編寫集成測試很有用。
2.什麼是多部分請求?
多部分請求是一種 HTTP POST 請求。它們允許在單個請求中發送各種文件或數據。
在多部分請求中,數據被分成多個部分。每個部分都有一個名稱,並以其自己的一組標頭開頭,標頭指示其包含的數據類型。每個部分之間的數據和邊界都被編碼。
3.設置
讓我們設置我們將使用的庫。
3.1. RestAssured 測試庫
RestAssured 是一個基於 Java 的庫,它提供了一種特定於領域的語言,用於為 RESTful Web 服務編寫自動化測試。
讓我們從將RestAssured庫添加到我們的pom.xml
開始:
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<version>5.3.0</version>
<scope>test</scope>
</dependency>
3.2.設置 Wiremock 服務器
我們將通過 RestAssured 發送多部分請求。在現實世界中,這些請求將到達我們要測試的目標服務器。為了我們的示例,我們將用模擬服務器替換這個真實服務器,並為此目的使用 Wiremock。
WireMock 是一個用於模擬 Web 服務的開源庫。它允許我們創建用於測試客戶端-服務器交互的存根。
讓我們將Wiremock庫添加到我們的pom.xml
中:
<dependency>
<groupId>com.github.tomakehurst</groupId>
<artifactId>wiremock</artifactId>
<version>2.27.2</version>
<scope>test</scope>
</dependency>
我們現在可以在 JUnit 測試中配置 Wiremock 服務器。我們將使服務器在每個測試方法之前啟動並在每個測試方法之後停止:
private WireMockServer wireMockServer;
@BeforeEach
void startServer() {
wireMockServer = new WireMockServer();
wireMockServer.start();
}
@AfterEach
void stopServer() {
wireMockServer.stop();
}
4. 使用 RestAssured 發送文件
我們將快速設置我們的模擬服務器,然後開始編寫我們的 RestAssured 測試。
4.1.文件處理
讓我們在test/resources
目錄中創建一個文件baeldung.txt
。為了準備發送文件,讓我們編寫兩個實用程序方法:
- 給定文件名,
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
設置為多部分請求中文件的控件名稱。
首先,我們將創建一個存根來接收這樣的請求。此外,我們將檢查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 測試請求
現在是時候關注我們將發送到服務器的多部分請求了。使用 RestAssured,請求規範遵循 given-when-then 範式。
首先,我們將使用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-Type
是text/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 多部分請求帶來更多的粒度。
六,結論
在本文中,我們使用 RestAssured 將多部分請求發送到模擬服務器。
我們看到瞭如何發送僅包含內容和控件名稱的文件,然後切換到構建更複雜的部分。
與往常一樣,代碼在 GitHub 上可用。