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 上找到。