Cannot test paging in Unit Test
I am trying to test paging for the following service method in a Java (Spring Boot) app:
@Override
public Page<PermissionDTO> findAll(PermissionCriteriaRequest request, Sort sort) {
final Page<Permission> permissions = repository.findAll(request, sort);
final List<PermissionDTO> permissionDTOs = permissions.getContent().stream().map(PermissionDTO::new)
.collect(Collectors.toList());
return new PageImpl<>(permissionDTOs, permissions.getPageable(), permissions.getTotalElements());
}
Here is my unit test method; here I set page to 1 and set size to 1 so that I get only one record for the first page. However, it returns all the 5 records and the PermissionCriteriaRequest
parameters do not make any sense. I think the problem is related to when(permissionRepository.findAll(request, null)).thenReturn(permissionPage)
because I set it to return all the 5 records. So, is it possible to test paging properly? Or is it meaningless under these circumstances?
@Test
public void test_findAll() {
final Permission permission1 = new Permission();
permission1.setName("Permission1");
final Permission permission2 = new Permission();
permission2.setName("Permission2");
final Permission permission3 = new Permission();
permission3.setName("Permission3");
final Permission permission4 = new Permission();
permission4.setName("Permission4");
final Permission permission5 = new Permission();
permission5.setName("Permission5");
final List<Permission> permissionList = new ArrayList<>();
permissionList.add(permission1);
permissionList.add(permission2);
permissionList.add(permission3);
permissionList.add(permission4);
permissionList.add(permission5);
final Page<Permission> permissionPage = new PageImpl<>(permissionList);
// here I set paging parameters
final PermissionCriteriaRequest request = new PermissionCriteriaRequest();
request.setNameFilter("Permission");
request.setPaginated(true);
request.setPage(1);
request.setSize(1);
when(permissionRepository.findAll(request, null)).thenReturn(permissionPage);
Page<PermissionDTO> result = permissionService.findAll(request, null);
assertEquals(permissionList.size(), result.getSize());
}
Update: Here is my repository code:
default Page<T> findAll(PageableCriteriaRequest criteriaRequest, Sort sort) {
final SearchSpecificationBuilder<T> builder =
new SearchSpecificationBuilder<>(criteriaRequest.getSearchCriteriaList());
return findAll(builder.build(), getPageable(criteriaRequest, sort));
}
Solution 1:
Yes, because of declaring mock's behaviour like
when(permissionRepository.findAll(request, null)).thenReturn(permissionPage);
you are just ignoring inner logic of request paging.
Now the question is what actually you want to check - if you want to test Repository paging implementation and the Repository is some 3rd library/Spring respository then maybe you do not need to test it - basically you should avoid testing libraries - they should be tested already by their developers. If Repository implementation is yours then such test case should be somewhere else already so still, in my opinion, you can ignore this issue you presented.
Thrid option is using 3rd party Repository implementation and the situation when you want to understand whether your findAll
method treats properly the paged result of Repository. Then you need to write your mock according to the original object's behaviour. There are two ways to do this:
- Either you are providing your own implementation instead of mock and in the
permissionRepository.findAll
method you are checking the request and returning proper count of records (they can be hardcoded in this test class implementation or even better provided by constructor parameter) - Either you are using some Mockito's magic to mock this behaviour due to what parameter was provided to mocked method call
Due to point 2 there are various ways to achieve this. For example take a look at: Making a mocked method return an argument that was passed to it