Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Mock Pageable object using Mockito?

I am developing Spring Boot + Data JPA + Mockito example. I've developed test case for the Pagination repository method, but its giving me below error.

org.mockito.exceptions.misusing.InvalidUseOfMatchersException: 
Misplaced or misused argument matcher detected here:

-> at com.xxxx.EmployeeServiceTest.test_findAllEmployeesPaginated(EmployeeServiceTest.java:152)
-> at com.xxxx.EmployeeServiceTest.test_findAllEmployeesPaginated(EmployeeServiceTest.java:152)
-> at com.xxxx.EmployeeServiceTest.test_findAllEmployeesPaginated(EmployeeServiceTest.java:152)
-> at com.xxxx.EmployeeServiceTest.test_findAllEmployeesPaginated(EmployeeServiceTest.java:152)

You cannot use argument matchers outside of verification or stubbing.
Examples of correct usage of argument matchers:
    when(mock.get(anyInt())).thenReturn(null);
    doThrow(new RuntimeException()).when(mock).someVoidMethod(anyObject());
    verify(mock).someMethod(contains("foo"))

This message may appear after an NullPointerException if the last matcher is returning an object 
like any() but the stubbed method signature expect a primitive argument, in this case,
use primitive alternatives.
    when(mock.get(any())); // bad use, will raise NPE
    when(mock.get(anyInt())); // correct usage use

Also, this error might show up because you use argument matchers with methods that cannot be mocked.
Following methods *cannot* be stubbed/verified: final/private/equals()/hashCode().
Mocking methods declared on non-public parent classes is not supported.

    at com.xxxx.EmployeeServiceTest.test_findAllEmployeesPaginated(EmployeeServiceTest.java:152)
    at org.junit.internal.runners.TestMethod.invoke(TestMethod.java:68)
    at org.junit.internal.runners.MethodRoadie$2.run(MethodRoadie.java:89)
    at org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:97)
    at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:87)
    at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:50)
    at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:34)
    at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:44)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:538)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:760)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:460)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:206)

Controller

@GetMapping()
public ResponseEntity<Page<Division>> getAllDivisionsPaginated(
    @RequestParam(required = false, value="page") Integer page, @RequestParam(required = false, value = "size") Integer size,
    @RequestParam(required = false) String sort,
    @RequestParam(required = false) String direction,
    Pageable pageable){

    Page<Division> divisions = divisionService.findAllDivisions(pageable, page, size, sort, direction);
    return new ResponseEntity<>(divisions, HttpStatus.OK);
}

Method:

public Page<Division> findAllEmployees(Pageable pageableReq, Integer page, Integer size, String sortBy, String direction) {
    Pageable pageable = Utils.sort(pageableReq, page, size, sortBy, direction);
    return employeeRepository.findByStatus(StatusEnum.A, pageable);
}

Another method:

public static Pageable sort(Pageable pageableReq, Integer page, Integer size, String sortBy, String direction) {
     Pageable pageable = null;
     if (page != null && size != null) {
         if (direction.equalsIgnoreCase("ASC"))
             pageable = PageRequest.of(page, size, Sort.by(sortBy).ascending());
         else if (direction.equalsIgnoreCase("DESC"))
             pageable = PageRequest.of(page, size, Sort.by(sortBy).descending());
     } else {
         pageable = pageableReq;
     }
    return pageable;
}

Test class:

@RunWith(PowerMockRunner.class)
@PrepareForTest({StatusEnum.class})
public class EmployeeServiceTest {

    @Mock
    private Employee employeeMock;

    @InjectMocks
    private EmployeeServiceImpl employeeServiceImpl;

    @Mock
    private EmployeeRepository employeeRepositoryMock;

    @Mock
    private EmployeeDto employeeDtoMock;

    @Mock
    private StatusEnum statusEnum;

    @Mock
    private Exception ex;

    @Mock
    private Pageable pageableMock;

    @Mock
    private Utils utils;

    @Mock
    private Page<Employee> employeePage;

    @Before
    public void setup() {
        mockStatic(StatusEnum.class);       
    }

    @Test
    public void test_findAllEmployeesPaginated() {
        Pageable pageable = PageRequest.of(0, 8);
        when(Utils.sort(pageable, anyInt(), anyInt(), anyString(), anyString())).thenReturn(pageableMock);
        when(employeeRepositoryMock.findByStatus(StatusEnum.A, pageableMock)).thenReturn(employeePage);
    }   
}
like image 442
PAA Avatar asked Sep 20 '25 20:09

PAA


1 Answers

  1. Pure Mockito can not mock static methods. (You would need to use the object reference utils instead of the Class Reference, but your code show that the method is static)
    If you want to use Powermock here you propably missing a mockStatic(Utils.class), but I am not sure whether this works together with the @Mock annotation.

  2. Also you have to change the call of the sort method. You have to use either only matchers or only real values. You can not mix them.

  3. Regarding the Runner @RunWith(PowerMockRunner.class). If you only write a pure JUnit 4 Test and Mocktio you should consider using the Mockito Runner instead.
    Else you need to initialize Mockito using MockitoAnnotations.initMocks(this); in the setup method.

(You didn´t tag your question with PowerMock, but I assume that might be incorrect.)

    @Before
    public void setup() throws Exception {
        MockitoAnnotations.initMocks(this);
        mockStatic(StatusEnum.class);       
    }

    @Test
    public void test_findAllEmployeesPaginated() {
        Pageable pageable = PageRequest.of(0, 8);

        mockStatic(Utils.class);
        when(Utils.sort(any(Pageable.class), anyInt(), anyInt(), anyString(), anyString())).thenReturn(pageableMock);
        when(employeeRepositoryMock.findByStatus(StatusEnum.A, pageableMock)).thenReturn(employeePage);
    }
like image 169
second Avatar answered Sep 22 '25 08:09

second