我面临的问题是我需要跟踪某些方法的调用,但只能使用指定的参数参数。请参阅下面的问题
@Test
public void simpleTest() {
ArgumentCaptor<Pear> captor = ArgumentCaptor.forClass(Pear.class);
Action action = mock(Action.class);
action.perform(new Pear());
action.perform(new Apple());
verify(action, times(1)).perform(captor.capture());
}
static class Action {
public void perform(IFruit fruit) {}
}
static class Pear implements IFruit {}
static class Apple implements IFruit {}
interface IFruit {}
但是得到:
org.mockito.exceptions.verification.TooManyActualInvocations:
action.perform(<Capturing argument>);
Wanted 1 time:
But was 2 times. Undesired invocation:
..
我做错了什么? Mockito v 1.10
说实话,这只是例如,我的代码更复杂,我不知道,Apple.class会调用多少次执行。这对我来说并不重要。我只需要验证执行调用(Pear.class)
UPD: 我需要验证Pear.class的方法被调用一次。让我们假设Action是Transaction并且执行是save(DomainObject)。所以我需要确保save(MyDomainObject)被调用一次,但无论之前保存了多少个对象。这个动作对于Test来说是原子的,我不能在这些操作之间重置模拟
答案 0 :(得分:3)
使用自定义捕获器类的解决方法
@Test
public void simpleTest() {
MyArgumentCaptor pearCaptor = new MyArgumentCaptor(Pear.class);
Action action = mock(Action.class);
action.perform(new Pear());
action.perform(new Apple());
verify(action, times(1)).perform((IFruit) argThat(pearCaptor));
System.out.println(pearCaptor.getMatchedObj());
}
class MyArgumentCaptor extends InstanceOf {
private Object matchedObj;
MyArgumentCaptor(Class<?> clazz) {
super(clazz);
}
@Override
public boolean matches(Object actual) {
boolean matches = super.matches(actual);
if (matches) {
matchedObj = actual;
}
return matches;
}
Object getMatchedObj() {
return matchedObj;
}
}
答案 1 :(得分:2)
要使用Pear
实例参数验证通话次数,您可以使用:
verify(action, times(1)).perform(isA(Pear.class));
比照。 Mockito. Verify method param to be a paticular class
请注意,自Mockito 2.1起,以下内容也适用:
verify(action, times(1)).perform(any(Pear.class));
比照public static T any(Class type)
...这是别名:isA(Class)...
...因为mockito 2.1.0 any()和anyObject()不再是别名 这种方法。
答案 2 :(得分:0)
您正在调用操作两次,但期待一次调用(times(1)
)。如果被调用两次,请尝试使用times(2)
,如果您不关心调用它的次数,请忽略它。
action.perform(new Pear());
action.perform(new Apple());