正在获取对mock的调用数



假设我想测试这样的代码:

class ClassToTest
  // UsedClass1 contains a method UsedClass2 thisMethod() {}
  UsedClass1 foo;
  void aMethod()
  {
    int max = new Random().nextInt(100);
    for(i = 0; i < max; i++)
    {
      foo.thisMethod().thatMethod();
    }
  }
}

如果我有这样的测试:

ClassToTest test;
UsedClass1 uc1;
UsedClass2 uc2;
@Test
public void thingToTest() {
  test = new ClassToTest();
  uc1 = mock(UsedClass1.class);
  uc2 = mock(UsedClass2.class);
  when(uc1.thisMethod()).thenReturn(uc2);
  when(uc2.thatMethod()).thenReturn(true);
  test.aMethod();
  // I would like to do this
  verifyEquals(callsTo(uc1.thisMethod()), callsTo(uc2.thatMethod()));
}

如何获取对uc1.thisMethod()uc2.thatMethod()的调用次数,以便检查它们的调用次数是否相同?

您可以这样做:

YourService serviceMock = Mockito.mock(YourService.class);
// code using YourService
// details of all invocations including methods and arguments
Collection<Invocation> invocations = Mockito.mockingDetails(serviceMock).getInvocations();
// just a number of calls of any mock's methods
int numberOfCalls = invocations.size();

如果你只想调用某个方法/参数组合,你可以用这样做

int specificMethodCall = Mockito.mockingDetails(serviceMock.myMethod(myParam)).getInvocations()

您可以存根您的方法,并增加一个计数器,如下所示:

final AtomicInteger countCall1 = new AtomicInteger();
Mockito.doAnswer(new Answer<UsedClass2>() {
    @Override
    public UsedClass2 answer(InvocationOnMock invocation) throws Throwable {
        countCall1.incrementAndGet();
        return uc2;
    }
}).when(uc1).thisMethod();

如果您知道支持调用方法的次数,则可以使用Mockito 的times()方法

//for example if had to be called 3 times
verify(uc1, times(3)).thisMethod();
verify(uc2, times(3)).thatMethod();

然而,我现在看到您多次随机调用该方法,所以这可能不是最好的答案,除非您截断随机数生成器以始终返回期望值。

您可以使用自定义的VerificationMode来计数调用,如下所示:

public class InvocationCounter {
    public static <T> T countInvocations(T mock, AtomicInteger count) {
        return Mockito.verify(mock, new Counter(count));
    }
    private InvocationCounter(){}
    private static class Counter implements VerificationInOrderMode, VerificationMode {
        private final AtomicInteger count;
        private Counter(AtomicInteger count) {
            this.count = count;
        }
        public void verify(VerificationData data) {
            count.set(data.getAllInvocations().size());
        }
        public void verifyInOrder(VerificationDataInOrder data) {
            count.set(data.getAllInvocations().size());
        }
        @Override
        public VerificationMode description(String description) {
            return VerificationModeFactory.description(this, description);
        }
    }
}

然后像这样使用它(也适用于void返回类型):

@Mock
private Function<String, Integer> callable;
AtomicInteger count= new AtomicInteger(); //here is the actual invocation count stored
countInvocations(callable,count).apply( anyString());
assertThat(count.get(),is(2));

相关内容

  • 没有找到相关文章