我想测试一下,Collection.sort(...)
是否被JMockit调用:
final List<Employee> employees = new ArrayList<>();
new Expectations() {
{
Collections.sort((List<Employee>) any);
result = employees;
}
};
assertThat(EmployeeRepository.getAllOrderedByName()).isSameAs(employees);
这是我在测试中的示例存储库的实现:
public class EmployeeRepository {
private static List<Employee> employees = new ArrayList<>();
public static List<Employee> getAllOrderedByName() {
Collections.sort(employees);
return employees;
}
}
当我运行单元测试时,我在Collections.sort
得到一个NullPointerException。由于调试器永远不会在getAllOrderedByName
方法中达到断点,因此在自我模拟中似乎是一个问题。
如何使用JMockit使用any
存根静态方法?
答案 0 :(得分:5)
在测试代码中,永远不会指定Collections
类进行模拟。因此,Collections.sort((List<Employee>) any);
调用会抛出NPE,因为any
的值为null并且执行了实际的sort
方法。
您可能认为期望块内的任何方法调用都会被自动模拟,但不 JMockit API的工作方式。相反,您需要通过声明使用@Mocked
,@NonStrict
,@Cascading
或{注释的模拟字段或模拟参数来明确指定模拟的类型。 {1}}。
此外,在这种情况下,@Capturing
是一个返回Collections.sort
的方法,因此记录返回值没有意义。
此外,像这样编写测试并不是我推荐的。它应该验证生成的集合是否已排序,而不是模拟void
类。
答案 1 :(得分:1)
这不能回答你的具体问题(过去我自己遇到了any
的困难,所以我尽量避免它!),但你可以使用MockUp代替:
final AtomicBoolean wasCalled = new AtomicBoolean();
new MockUp<Collections> () {
@Mock
public <T extends Comparable<? super T>> void sort(List<T> list) {
wasCalled.set(true);
//no-op otherwise
}
};
assertThat(EmployeeRepository.getAllOrderedByName()).isSameAs(employees);
assertTrue(wasCalled.get());
答案 2 :(得分:1)
如果我是你,我不会这样做。
首先,测试Comparable
上的Employee
是否有效。
然后创建Employee
类的模拟。注意:在这里使用mockito,但我想这可以适应jmockit(我从未使用过):
private static final int NR_MOCKS = 20;
// ....
List<Employee> sorted = new ArrayList<>(NR_MOCKS);
for (int i = 0; i < NR_MOCKS; i++)
sorted.add(mock(Employee.class));
// Create a shuffled list of the sorted list
List<Employee> shuffled = new ArrayList<>(sorted);
Collections.shuffe(shuffled);
// Inject shuffled into repository
// Stubs
for (int i1 = 0; i1 < NR_MOCKS; i1++)
for (int i2 = 0; i2 < NR_MOCKS; i2++)
when(sorted.get(i1).compareTo(sorted.get(i2))).thenReturn(i2 - i1);
List<Employee> actual = EmployeeRepository.getAllOrderedByName();
assertEquals(actual, sorted);
它不仅检查列表是否最终排序(因为您事先已经测试了Comparable
实现),但不关心使用了哪种排序算法;它只是工作(tm)。