繁体   English   中英

Mockito验证Callable对象是否失败

[英]Mockito verify not failing on Callable object

对于执行对Callable参数的操作的方法,我有以下代码:

public static <T> T queryWithRetry(Callable<T> query, int maxTries, int retryIntervalInMilliseconds) throws MongoServiceException, InterruptedException {
    int tries = MAX_TRIES;
    while (tries-- > 0) {
      try {
        return query.call();
      } catch (TimeoutException e) {
        LOGGER.debug(String.format("Query timed out. Retrying attempt %d/%d", MAX_TRIES - tries, MAX_TRIES));
        Thread.sleep(RETRY_INTERVAL_IN_MILLISECONDS);
        continue;
    }
    throw new RandomException();
  }

我正在使用Mockito尝试验证在抛出RandomException之前, MAX_TRIESquery.call()完全尝试了MAX_TRIES次。 我尝试使用以下测试代码执行此操作:

public class CallableQueryTest {
  private static final int MAX_TRIES = 3;
  private static final int RETRY_INTERVAL_IN_MILLISECONDS = 100;

  @Mock
  private Callable<Document> mockCallable;

  @Rule
  public ExpectedException thrown = ExpectedException.none();

  @Before
  public void setUp() throws Exception {
    mockCallable = Mockito.mock(Callable.class);
  }

  @Test
  public void testQueryConfigThrowsRandomExceptionOnTimeout() throws Exception {
    Mockito.when(mockCallable.call()).thenThrow(new TimeoutException("timeout"));

    thrown.expect(RandomException.class);    
    Mockito.verify(mockCallable, Mockito.atMost(1)).call();
    MongoQueryUtils.queryWithRetry(mockCallable, MAX_TRIES, RETRY_INTERVAL_IN_MILLISECONDS);
  }
}

Mockito代码成功测试了该方法引发了RandomException ,但是不正确地说测试通过了。

该测试应该失败,因为我写了Mockito应该验证一次最多执行一次mockCallable.call() ,但是据我了解,它被称为MAX_TRIES次(设置为3)。

有人可以解释这种现象,并提供有关如何正确测试调用mockCallable.call()次数的mockCallable.call()吗?

您的测试有很多错误。 这是您想要做的事情:

private static final int MAX_TRIES = 3;
private static final int RETRY_INTERVAL_IN_MILLISECONDS = 100;

@Mock
private Callable<String> mockCallable;

@Test
public void testQueryConfigThrowsRandomExceptionOnTimeout() throws Exception {
    when(mockCallable.call()).thenThrow(new IllegalArgumentException("timeout"));
    try {
        queryWithRetry(mockCallable, MAX_TRIES, RETRY_INTERVAL_IN_MILLISECONDS);
        fail("should have thrown");
    } catch (RuntimeException re) {
        // as expected
    }
    verify(mockCallable, Mockito.times(3)).call();
}

(请注意:我更改了测试的异常类型;但这应该很明显)。

所以,你错了:

  • 我建议使用@RunWith(MockitoJUnitRunner.class) ,然后使用@Mock批注。 您具有@Mock批注以及用于同一字段的调用Mockito.mock()的设置方法。 那是多余的。 可以将注释与@RunWith一起使用,或者在设置方法中调用MockitoAnnotations.initMocks()
  • 与模拟对象互动 ,必须调用verify() 试想一下有柜台的模拟游戏。 在进行交互之前,计数器全为0。因此, 触发对模拟的调用之前,没有必要向模拟询问其计数器。
  • 我对JUnit规则不熟悉; 因此,我将测试改写为没有它就可以工作。 如果要使用JUnit规则进行异常处理; 留给读者作为练习。

暂无
暂无

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

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