Reputation: 1034
I'm using the reactive web test alternative that comes with Spring Boot 2, and i'm trying to build a test for a controller like this:
@RestController
@RequestMapping("/users")
public class UserController{
@Autowired
private UserService service;
@GetMapping
public Page<UserDTO> get(Pageable pageable){
return service.get(pageable);
}
}
The test looks like this:
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class UsersTest{
@Autowired
private WebTestClient webClient;
@Test
public void test(){
List<UserDTO> userList = webClient.get()
.uri("/users")
.exchange()
.expectStatus().isOk()
.expectBodyList(UserDTO.class).hasSize(1)
.returnResult()
.getResponseBody();
assertNotNull(userList.get(1).getId());
}
}
The result in the request is in fact a list of 1 element, but is not properly, because the structure of the response is:
{
"content": [
{
"id": 1,
"name": "John",
"lastName": "Doe",
"active": true
}
],
"pageable": {
"sort": {
"sorted": false,
"unsorted": true
},
"offset": 0,
"pageSize": 25,
"pageNumber": 0,
"unpaged": false,
"paged": true
},
"totalPages": 1,
"totalElements": 1,
"last": true,
"size": 25,
"number": 0,
"numberOfElements": 1,
"first": true,
"sort": {
"sorted": false,
"unsorted": true
}
}
So when i get the id value of that first element I obtain a null value. And the test fails.
Is there a way (maybe a Exchange Filter Function) than makes the WebTestClient understand pageable responses?
Thanks in advance for any help.
Upvotes: 1
Views: 3540
Reputation: 1034
I consider that Dirk Deyne solution is better than mine, but maybe for someone it could be useful.
I built these 3 classes using lombok:
@Data
@NoArgsConstructor
public class CustomResponsePage<T> {
List<T> content;
CustomPageable pageable;
Integer totalPages;
Integer totalElements;
Boolean last;
Integer size;
Integer number;
Long numberOfElements;
Boolean first;
CustomSort sort;
}
@Data
@NoArgsConstructor
public class CustomPageable{
CustomSort sort;
Long offset;
Integer pageSize;
Integer pageNumber;
Boolean unpaged;
Boolean paged;
}
@Data
@NoArgsConstructor
public class CustomSort {
Boolean sorted;
Boolean unsorted;
}
An then, I modified the test like this:
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class UsersTest{
@Autowired
private WebTestClient webClient;
@Test
public void test(){
PagedUserDTO pagedUserList = webClient.get()
.uri("/users")
.exchange()
.expectStatus().isOk()
.expectBody(UserDTO.class)
.returnResult(PagedUserDTO.class)
.getResponseBody();
assertTrue(pagedUserList.getContent().size() == 0);
}
private static class PagedUserDTO extends CustomResponsePage<UserDTO> { }
}
Notice the PagedUserDTO class created at the end of the test.
It's a still in progress structure because it doesn't consider when there are order columns in the response, but in my case I don't need them.
Upvotes: 0
Reputation: 6936
I think WebTestClient can understand pageable responses. The structure of the response is json, and WebTestClient provides a way to interact with json.
So if you want to test if the response contains 1 user that has an id. You can do:
webClient.get()
.uri("/users")
.exchange()
.expectBody()
.jsonPath("$.numberOfElements").isEqualTo(1)
.jsonPath("$.content[0].id").isNotEmpty();
Upvotes: 4