简体   繁体   English

Mockito的论证Captor行为

[英]Mockito's Argument Captor Behavior

I am facing with issue where I need to track invocation of some method but only with specified argument parameter. 我面临的问题是我需要跟踪某些方法的调用,但只能使用指定的参数参数。 See issue below 见下面的问题

@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 {}

But getting : 但得到:

org.mockito.exceptions.verification.TooManyActualInvocations: 
action.perform(<Capturing argument>);
Wanted 1 time:
But was 2 times. Undesired invocation:
..

What I am doing wrong? 我做错了什么? Mockito v 1.10 Mockito v 1.10

To be honest it is just for example and my code more complicated and I don't know, how many times perform will be invoked with Apple.class. 说实话,这只是例如,我的代码更复杂,我不知道,Apple.class会调用多少次执行。 It doesn't matter for me. 对我来说没关系。 I need to verify only call of perform(Pear.class) 我只需要验证执行调用(Pear.class)

UPD: I need to verify that method with Pear.class was called once. UPD:我需要验证Pear.class的方法被调用一次。 Lets imagine that Action is Transaction and perform is save(DomainObject). 让我们假设Action是Transaction并且执行是save(DomainObject)。 So I need to be sure that save(MyDomainObject) was called once, but no matter how many Objects were saved before. 所以我需要确保save(MyDomainObject)被调用一次,但无论之前保存了多少个对象。 This action is atomic for Test and I can't reset mock between these operations 这个动作对于Test是原子的,我无法在这些操作之间重置模拟

Workaround using a custom captor class 使用自定义captor类的变通方法

  @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;
    }
  }

To verify the number of calls with Pear instances parameters, you may use : 要使用Pear实例参数验证调用次数,您可以使用:

verify(action, times(1)).perform(isA(Pear.class));

Cf. 参看 Mockito. 的Mockito。 Verify method param to be a paticular class 验证方法参数是一个特殊的类

Note that since Mockito 2.1, the following would also work : 请注意,从Mockito 2.1开始,以下内容也适用:

verify(action, times(1)).perform(any(Pear.class));

cf. 比照 public static T any(Class type) public static T any(类型)

...This is an alias of: isA(Class)... ...这是别名:isA(Class)......

...Since mockito 2.1.0 any() and anyObject() are not anymore aliases of this method. ...由于mockito 2.1.0 any()和anyObject()不再是此方法的别名。

You are calling action twice, but expecting one call ( times(1) ). 您正在调用操作两次,但期待一次调用( times(1) )。 Try with times(2) if it is called twice or omit it if you don't care how many times you call it. 如果被调用两次,请尝试使用times(2)如果不关心多少次,则省略它。

action.perform(new Pear());
action.perform(new Apple());

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM