Home > Blockchain >  How to fetch response using WebTestClient
How to fetch response using WebTestClient

Time:05-12

I am new to Reactive programming and having trouble testing. 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:

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:

@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.

CodePudding user response:

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..

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

CodePudding user response:

There are several questions here

  1. To deserialize generic type use ParameterizedTypeReference.
  2. The you could use WebTestClient API to validate response and it's not necessary to block. For example value or consumeWith allows to access the body and assert result.
WebTestClient.get()
        .uri("/some-mapping")
        .exchange()
        .expectStatus().isOk()
        .expectBody(new ParameterizedTypeReference<Slice<SimpleEntity>>() {})
        .value(slice -> {
            assertEquals(...);
        });
  • Related