java Mockito:等待与参数匹配的调用

z9zf31ra  于 2022-12-02  发布在  Java
关注(0)|答案(2)|浏览(141)

我正在编写一个selenium测试,并使用mockito验证服务器行为。具体来说,当单击一个按钮时,我希望确保页面控制器调用我模拟的依赖项上的特定方法。
因为这是一个selenium测试,我需要等待在另一个线程中调用mock,所以我使用mockito timeout。

verify(myMock, timeout(5000).times(1)).myMethod("expectedArg");

我遇到的问题是myMethod被调用了很多次... timeout只等待第一次调用,而不是等待与预期参数匹配的调用。如果我使用Thread. sleep(50000)而不是timeout(50000),它会按预期工作...但这很脏,所以我希望避免它。
如何等待myMethod被预期的输入调用?

mwg9r5ms

mwg9r5ms1#

如果您能够设置预期的固定调用次数,则可以使用ArgumentCaptor

import static org.hamcrest.CoreMatchers.hasItem;

@Captor ArgumentCaptor<String> arg;

@Before
public void setUp() throws Exception {
    // init the @Captor
    initMocks(this);
}

@Test
public void testWithTimeoutCallOrderDoesntMatter() throws Exception {
    // there must be exactly 99 calls
    verify(myMock, timeout(5000).times(99)).myMethod(arg.capture());
    assertThat(arg.getAllValues(), hasItem("expectedArg"));
}

另一种方法是指定所有要验证的期望值,但这些值需要按照调用它们的确切顺序提供。与上述解决方案的不同之处在于,即使使用一些未验证的参数额外调用mock,这种方法也不会失败。换句话说,不需要知道总调用次数。代码示例:

@Test
public void testWithTimeoutFollowingCallsDoNotMatter() throws Exception {
    // the order until expected arg is specific
    verify(callback, timeout(5000)).call("firstExpectedArg");
    verify(callback, timeout(5000)).call("expectedArg");
    // no need to tell more, if additional calls come after the expected arg
    // verify(callback, timeout(5000)).call("randomArg");
}
y53ybaqx

y53ybaqx2#

这不是一个超级干净的解决方案,但你可以这样做(XX是这里假定的返回类型):

final CountDownLatch latch = new CountDownLatch(1);

doReturn(new Answer<XX>()
    {
        @Override
        public XX answer(InvocationOnMock invocation)
        {
            latch.countDown();
            return someInstanceOfXX;
        }
    }
).when(myMock).myMethod("expectedArg");

然后,若要测试是否呼叫方法,请执行:

try {
    assertTrue(latch.await(5L, TimeUnit.SECONDS));
} catch (InterruptedException e) {
    // Urgh... Failed. Deal with it and:
    Thread.currentThread().interrupt();
}

相关问题