Search code examples
javacollectionsmockingstatic-methodsjmockit

Stubbing a static method with JMockit using 'any'


I want to test, whether Collection.sort(...) is called or not with JMockit:

final List<Employee> employees = new ArrayList<>();
new Expectations() {
  {
    Collections.sort((List<Employee>) any);
    result = employees;
  }
};

assertThat(EmployeeRepository.getAllOrderedByName()).isSameAs(employees);

This is the implementation of my example repository under test:

public class EmployeeRepository {

  private static List<Employee> employees = new ArrayList<>();

  public static List<Employee> getAllOrderedByName() {
    Collections.sort(employees);
    return employees;
  }
}

When I run the unit test I get a NullPointerException at Collections.sort. It seems like it is a problem in the mocking it self since the debugger never reaches a break point in the getAllOrderedByName method.

How can I stub static methods using any with JMockit?


Solution

  • In your test code, the Collections class is never specified to be mocked. Therefore, that Collections.sort((List<Employee>) any); call throws an NPE because the value of any is null and the actual sort method is executed.

    You probably assumed that any method call inside an expectation block would be automatically mocked, but that's not how the JMockit API works. Instead, you need to explicitly specify which types are mocked, by declaring a mock field or a mock parameter annotated with @Mocked, @NonStrict, @Cascading, or @Capturing.

    Also, in this case Collections.sort is a method that returns void, so it doesn't make sense to record a return value for it.

    Furthermore, writing the test like this is not what I would recommend anyway. It should instead verify that the resulting collection is sorted, without ever mocking the Collections class.