如何在 Spring Boot Reactive Webflux 的测试中解析 String[]?
How to parse a String[] in tests with Spring Boot Reactive Webflux?
在我的 spring 启动应用程序中,我想编写一个网络测试。
我的应用程序returns 一个字符串列表。但是,测试会生成一个只有一个元素的列表(完整的 json 作为字符串)。
我的(最小示例)生产代码:
@SpringBootApplication
public class BackendApplication {
public static void main(String[] args) {
SpringApplication.run(BackendApplication.class, args);
}
}
@RestController
@RequestMapping("/allBoxes")
class WhosebugController {
@GetMapping
public List<String> getNamesOfAllBoxes() {
return List.of("Fruits", "Regional");
}
}
我的测试class:
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class WhosebugControllerTest {
@Autowired
WebTestClient webTestClient;
@Test
void whenListOfStringsEndpoint_thenExpectListOfStrings(){
// When
List<String> actual = webTestClient.get()
.uri("/allBoxes")
.exchange()
.expectStatus().is2xxSuccessful()
.expectBodyList(String.class)
.returnResult()
.getResponseBody();
// Then
Assertions.assertEquals(List.of("Fruits", "Regional"), actual);
}
}
我的 Maven 依赖项(spring boot 2.7.0 parent):
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
测试失败:
org.opentest4j.AssertionFailedError:
Expected :[Fruits, Regional]
Actual :[["Fruits","Regional"]]
但是,如果我通过邮递员访问生产应用程序,我会收到:
["Fruits","Regional"]
为什么反应式 WebTestClient 不解析这个 json,而是创建一个只有一个字符串的数组?我怎样才能告诉它解析字符串并给我一个字符串列表(以我的两个项目作为元素)?
检查 Jackson2Decoder
或 Spring WebClient
的默认行为
对于 multi-value 发布者,WebClient
默认情况下使用 Flux#collectToList()
收集值,然后 serializes
结果集合。
您将需要 deserialize
相应地。
如果你更换
.expectBodyList(String.class)
来自
.expectBody(new ParameterizedTypeReference<List<String>>() {})
有效。像这样:
@Test
void whenListOfStringsEndpoint_thenExpectListOfStrings(){
// When
List<String> actual = webTestClient.get()
.uri("/allBoxes")
.exchange()
.expectStatus().is2xxSuccessful()
.expectBody(new ParameterizedTypeReference<List<String>>() {})
.returnResult()
.getResponseBody();
// Then
Assertions.assertEquals(List.of("Fruits", "Regional"), actual);
}
在我的 spring 启动应用程序中,我想编写一个网络测试。
我的应用程序returns 一个字符串列表。但是,测试会生成一个只有一个元素的列表(完整的 json 作为字符串)。
我的(最小示例)生产代码:
@SpringBootApplication
public class BackendApplication {
public static void main(String[] args) {
SpringApplication.run(BackendApplication.class, args);
}
}
@RestController
@RequestMapping("/allBoxes")
class WhosebugController {
@GetMapping
public List<String> getNamesOfAllBoxes() {
return List.of("Fruits", "Regional");
}
}
我的测试class:
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class WhosebugControllerTest {
@Autowired
WebTestClient webTestClient;
@Test
void whenListOfStringsEndpoint_thenExpectListOfStrings(){
// When
List<String> actual = webTestClient.get()
.uri("/allBoxes")
.exchange()
.expectStatus().is2xxSuccessful()
.expectBodyList(String.class)
.returnResult()
.getResponseBody();
// Then
Assertions.assertEquals(List.of("Fruits", "Regional"), actual);
}
}
我的 Maven 依赖项(spring boot 2.7.0 parent):
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
测试失败:
org.opentest4j.AssertionFailedError:
Expected :[Fruits, Regional]
Actual :[["Fruits","Regional"]]
但是,如果我通过邮递员访问生产应用程序,我会收到:
["Fruits","Regional"]
为什么反应式 WebTestClient 不解析这个 json,而是创建一个只有一个字符串的数组?我怎样才能告诉它解析字符串并给我一个字符串列表(以我的两个项目作为元素)?
检查 Jackson2Decoder
或 Spring WebClient
对于 multi-value 发布者,WebClient
默认情况下使用 Flux#collectToList()
收集值,然后 serializes
结果集合。
您将需要 deserialize
相应地。
如果你更换
.expectBodyList(String.class)
来自
.expectBody(new ParameterizedTypeReference<List<String>>() {})
有效。像这样:
@Test
void whenListOfStringsEndpoint_thenExpectListOfStrings(){
// When
List<String> actual = webTestClient.get()
.uri("/allBoxes")
.exchange()
.expectStatus().is2xxSuccessful()
.expectBody(new ParameterizedTypeReference<List<String>>() {})
.returnResult()
.getResponseBody();
// Then
Assertions.assertEquals(List.of("Fruits", "Regional"), actual);
}