1. 概述
在这个教程中,我们将使用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 服务。 它允许我们为测试客户端-服务器交互创建代理。
请在 pom.xml
中添加 Wiremock 库:
<dependency>
<groupId>org.wiremock</groupId>
<artifactId>wiremock-standalone</artifactId>
<version>3.3.1</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 文件发送到 /upload URL。我们将 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 中,请求规范遵循给定-然后-然后的模式。
首先,我们将使用 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 分段请求带来更多的细节。
6. 结论
在这篇文章中,我们使用 RestAssured 向模拟服务器发送了分段请求。
我们看到了如何仅使用内容和控制名称发送文件,然后切换到构建更复杂的部分。
如往常一样,代码可在 GitHub 上找到。