繁体   English   中英

如何使用 WebTestClient 获取响应

[英]How to fetch response using WebTestClient

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

一个实体:

class SimpleEntity{
  @Id    
  int id;
  String name;
}

相关存储库:

class SimpleEntityRepository extends JpaRepository<SimpleEntity, Integer>{

  Slice<SimpleEntity> findByName(String name, Pageable pageable);

}

相关服务:

class SimpleEntityService{
  @Autowired
  SimpleEntityRepository repository;

  public Mono<Slice<SimpleEntity>> findByName(String name, Pageable pageable){
    //All business logic excluded
    return Mono.just(
      repository.findByName(name, pageable);
    );
  }

}

一个相关的controller:

class SimpleEntityController{

  @Autowired
  SimpleEntityService service;
  
  @RequestMapping("/some-mapping")
  public Mono<Slice<SimpleEntity>> findByName(@Requestparam String name, int pageNum){
    return service.findByName(name, Pageable.of(pageNum, 100));
  }

}

现在,在我的集成测试中,我尝试使用 WebTestClient 访问 controller,但我无法理解如何获取和反序列化响应:

@Test
public void someIntegrationTest(){
     WebTestClient.ResponseSpec responseSpec = webTestClient.get()
          .uri(URI)
          .accept(MediaType.APPLICATION_JSON)
          .exchange();
    responseSpec.returnResult(SliceImpl.class).getResponseBody.blockFirst();
} 

最后一行抛出以下异常:

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 并能够对其执行断言。

进行交换后,如果是列表或对象,则可以根据您的响应执行 expectBody 或 expectBodyList ,并且您具有包含等功能。

webClient
    .get()
    .uri("your url here")
    .contentType(MediaType.APPLICATION_JSON)
    .exchange()
    .expectStatus()
    .isOk()
    .expectBodyList(YOUROBJECT.class)
    .contains(object that you expect)

这里有几个问题

  1. 要反序列化泛型类型,请使用ParameterizedTypeReference
  2. 您可以使用WebTestClient API 来验证响应,并且没有必要阻止。 例如valueconsumeWith允许访问主体和断言结果。
WebTestClient.get()
        .uri("/some-mapping")
        .exchange()
        .expectStatus().isOk()
        .expectBody(new ParameterizedTypeReference<Slice<SimpleEntity>>() {})
        .value(slice -> {
            assertEquals(...);
        });

在 spring 引导的 2022 版本中,如果发生故障,您将在断言失败日志中看到请求和响应。 如果您有兴趣在断言未失败的情况下记录请求和响应,则可以使用客户端调用的结果,如下所示(在 Kotlin 中)。

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

这是通过returnResult “退出”链并使用consumeWith访问ExchangeResult.toString()来实现的,后者可以方便地打印请求和响应。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM