简体   繁体   English

如何使用 WebTestClient 获取响应

[英]How to fetch response using WebTestClient

I am new to Reactive programming and having trouble testing.我是 Reactive 编程的新手,在测试时遇到了麻烦。 I have a very simple scenario,我有一个非常简单的场景,

an Entity:一个实体:

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

a related repository:相关存储库:

class SimpleEntityRepository extends JpaRepository<SimpleEntity, Integer>{

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

}

a related service:相关服务:

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);
    );
  }

}

a related controller:一个相关的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));
  }

}

Now, in my integrations tests, I am trying hit the controller using WebTestClient but I am unable to understand how can I fetch and deserialize the response:现在,在我的集成测试中,我尝试使用 WebTestClient 访问 controller,但我无法理解如何获取和反序列化响应:

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

The last line throws the following exception:最后一行抛出以下异常:

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"])

What I essentially want is to be able to get the Slice and be able to perform assertions over it.我本质上想要的是能够获得 Slice 并能够对其执行断言。

After you do exchange you can do expectBody or expectBodyList based on your response if is list or object and than you have functions like contain etc..进行交换后,如果是列表或对象,则可以根据您的响应执行 expectBody 或 expectBodyList ,并且您具有包含等功能。

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

There are several questions here这里有几个问题

  1. To deserialize generic type use ParameterizedTypeReference .要反序列化泛型类型,请使用ParameterizedTypeReference
  2. The you could use WebTestClient API to validate response and it's not necessary to block.您可以使用WebTestClient API 来验证响应,并且没有必要阻止。 For example value or consumeWith allows to access the body and assert result.例如valueconsumeWith允许访问主体和断言结果。
WebTestClient.get()
        .uri("/some-mapping")
        .exchange()
        .expectStatus().isOk()
        .expectBody(new ParameterizedTypeReference<Slice<SimpleEntity>>() {})
        .value(slice -> {
            assertEquals(...);
        });

In 2022 versions of spring boot, in the event of a failure you will see the request and response as part of your assertion failure logs.在 spring 引导的 2022 版本中,如果发生故障,您将在断言失败日志中看到请求和响应。 If you are interested in logging the request and response in the case where your assertions don't fail, you can consume the result of the client call as shown below(in Kotlin).如果您有兴趣在断言未失败的情况下记录请求和响应,则可以使用客户端调用的结果,如下所示(在 Kotlin 中)。

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

This works by "exiting" the chain via returnResult and using consumeWith to access ExchangeResult.toString() which conveniently prints the request and response.这是通过returnResult “退出”链并使用consumeWith访问ExchangeResult.toString()来实现的,后者可以方便地打印请求和响应。

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

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