我想做以下工作,但我不知道如何正确地模拟每个行为。 (代码取自相关问题Testing Java enhanced for behavior with Mockito)
@Test
public void aa() {
Collection<String> fruits;
Iterator<String> fruitIterator;
fruitIterator = mock(Iterator.class);
when(fruitIterator.hasNext()).thenReturn(true, true, true, false);
when(fruitIterator.next()).thenReturn("Apple")
.thenReturn("Banana").thenReturn("Pear");
fruits = mock(Collection.class);
when(fruits.iterator()).thenReturn(fruitIterator);
doCallRealMethod().when(fruits).forEach(any(Consumer.class));
// this doesn't work (it doesn't print anything)
fruits.forEach(f -> {
mockObject.someMethod(f);
});
// this works fine
/*
int iterations = 0;
for (String fruit : fruits) {
mockObject.someMethod(f);
}
*/
// I want to verify something like this
verify(mockObject, times(3)).someMethod(anyString());
}
非常感谢任何帮助。
答案 0 :(得分:1)
forEach
界面的方法Collection
是&#34;后卫&#34;方法;它不使用Iterator
,而是调用传递给方法的Consumer
。
如果您使用的是Mockito版本2+(*),则可以要求调用forEach
接口的默认方法Collection
:
Mockito.doCallRealMethod().when(fruits).forEach(Mockito.any(Consumer.class));
请注意&#34;后卫&#34;方法实际上是要求Iterator
遍历集合,因此将使用您在测试中模拟的Iterator
。如果被模拟的集合没有提供Iterator
,那么它就无法工作,就像使用when(fruits.iterator()).thenReturn(fruitIterator)
(*):自第2版以来,Mockito已添加了支持Java 8默认(&#34; defender&#34;)方法的可能性 - 您可以检查跟踪问题here。
答案 1 :(得分:0)
Iterator mockIterator = mock(Iterator.class);
doCallRealMethod().when(fruits).forEach(any(Consumer.class));
when(fruits.iterator()).thenReturn(mockIterator);
when(mockIterator.hasNext()).thenReturn(true, false);
when(mockIterator.next()).thenReturn(mockObject);