簡體   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