Spring Boot 如何使用WebTestClient提取响应

6kkfgxo0  于 2022-11-23  发布在  Spring
关注(0)|答案(3)|浏览(324)

我是一个React式编程新手,在测试时遇到了麻烦。我有一个非常简单的场景,
实体:

  1. class SimpleEntity{
  2. @Id
  3. int id;
  4. String name;
  5. }

相关存储库:

  1. class SimpleEntityRepository extends JpaRepository<SimpleEntity, Integer>{
  2. Slice<SimpleEntity> findByName(String name, Pageable pageable);
  3. }

相关服务:

  1. class SimpleEntityService{
  2. @Autowired
  3. SimpleEntityRepository repository;
  4. public Mono<Slice<SimpleEntity>> findByName(String name, Pageable pageable){
  5. //All business logic excluded
  6. return Mono.just(
  7. repository.findByName(name, pageable);
  8. );
  9. }
  10. }

相关控制器:

  1. class SimpleEntityController{
  2. @Autowired
  3. SimpleEntityService service;
  4. @RequestMapping("/some-mapping")
  5. public Mono<Slice<SimpleEntity>> findByName(@Requestparam String name, int pageNum){
  6. return service.findByName(name, Pageable.of(pageNum, 100));
  7. }
  8. }

现在,在我的集成测试中,我尝试使用WebTestClient访问控制器,但是我不知道如何获取和反序列化响应:

  1. @Test
  2. public void someIntegrationTest(){
  3. WebTestClient.ResponseSpec responseSpec = webTestClient.get()
  4. .uri(URI)
  5. .accept(MediaType.APPLICATION_JSON)
  6. .exchange();
  7. responseSpec.returnResult(SliceImpl.class).getResponseBody.blockFirst();
  8. }

最后一行抛出以下异常:
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of org.springframework.data.domain.Pageable (no Creators, like default constructor, exist): abstract types either need to be mapped to concrete types, have custom deserializer, or contain additional type information at [Source: UNKNOWN; byte offset: #UNKNOWN] (through reference chain: org.springframework.data.domain.SliceImpl["pageable"])
我本质上想要的是能够获得Slice并能够在其上执行Assert。

mwngjboj

mwngjboj1#

在完成交换之后,您可以根据您的响应(如果是列表或对象)执行expectBody或expectBodyList,然后您可以使用contain等函数。

  1. webClient
  2. .get()
  3. .uri("your url here")
  4. .contentType(MediaType.APPLICATION_JSON)
  5. .exchange()
  6. .expectStatus()
  7. .isOk()
  8. .expectBodyList(YOUROBJECT.class)
  9. .contains(object that you expect)
kiayqfof

kiayqfof2#

这里有几个问题
1.若要还原序列化泛型型别,请使用ParameterizedTypeReference
1.您可以使用WebTestClient API来验证响应,并且不需要阻塞。例如,valueconsumeWith允许访问主体并Assert结果。

  1. WebTestClient.get()
  2. .uri("/some-mapping")
  3. .exchange()
  4. .expectStatus().isOk()
  5. .expectBody(new ParameterizedTypeReference<Slice<SimpleEntity>>() {})
  6. .value(slice -> {
  7. assertEquals(...);
  8. });
yyhrrdl8

yyhrrdl83#

在2022版本的spring Boot 中,如果发生了失败,您会看到请求和响应作为Assert失败日志的一部分。如果您有兴趣在Assert没有失败的情况下记录请求和响应,您可以使用客户端调用的结果,如下所示(在Kotlin中)。

  1. webTestClient
  2. .get()
  3. .uri("/something")
  4. .exchange()
  5. .expectStatus().isOk
  6. .returnResult<String>() //Generic type doesn't matter in this example
  7. .consumeWith { logger.info { it } }

其工作原理是通过returnResult“退出”链,并使用consumeWith访问ExchangeResult.toString()ExchangeResult.toString()可以方便地打印请求和响应。

相关问题