簡體   English   中英

如何在集成測試中等待某些操作

[英]How to wait in integration test for some operations

我使用測試容器對 docker 進行了集成測試。 在容器上我運行 jms。 在測試中,我將消息放在隊列中。

我如何在測試中等待以使其填充到 jms 上?

在本地機器上它可以工作,但在 jenkins 上它失敗了,所以我必須添加

    Thread.sleep(3000);

但這很討厭。 org.awaitility 似乎錯過了用法:

await().atMost(2, TimeUnit.SECONDS).until(() -> return true));

我只需要暫停一下以使 jms 傳播(放入 jms 隊列)並等待偵聽器采取行動,即將消息放入數據庫。 然后我必須調用 get rest 端點來查看它是否有效。

使用主題會更容易,因為我會在主題上創建測試監聽器。 但它是隊列,可以有監聽器來獲取消息。

org.awaitility與 JMS QueueBrowser一起使用,例如:

@Test
public void myTest() throws Exception {
   ...
   await().atMost(2, TimeUnit.SECONDS).until(() -> return queueIsEmpty(queueName)));
   ...
}

private boolean queueIsEmpty(String queueName) {
   ConnectionFactory cf = new MyBrokersConnectionFactory();
   Connection connection = cf.createConnection();
   Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
   QueueBrowser browser = session.createBrowser(session.createQueue(queueName));
   Enumeration enumeration = senderBrowser.getEnumeration();
   while (enumeration.hasMoreElements()) {
      return false;
   }
   return true;
}

QueueBrowser只讀的,因此不會有實際消耗消息的危險。

另一種可能的選擇是創建一個具有已交易session 的消費者,然后嘗試接收消息。 如果您確實收到了一條消息,您可以回滾事務並關閉消費者。

使用重試(例如Spring RetryTemplateFailsafe Retry Policy )來提高集成測試執行時間:

  • 重試 SQL 查詢,直到出現記錄
  • 重試 REST 端點,直到成功

這里是一個等待 DB 記錄的例子; 根據您的需要調整政策:

RetryTemplate retryTemplate = new RetryTemplate();
retryTemplate.setBackOffPolicy(new FixedBackOffPolicy());
retryTemplate.setRetryPolicy(new SimpleRetryPolicy(
         10, Collections.singletonMap(AssertionError.class, true)));
retryTemplate.execute(retryContext -> {
    List<MyRecord> records = jdbcTemplate.query("select ...");
    Assert.assertEquals(1, records.size());
    return null;
});

使用 Failsafe,您可以創建一個RetryPolicy ,將 maxRetries 設置為-1 ,這樣它將無限次重試,直到執行完成並出現異常。 前任:

RetryPolicy<Object> rp = RetryPolicy<Object>.builder()
  .withMaxRetries(-1);
  .build();

Failsafe.with(retryPolicy).run(() -> {
    List<MyRecord> records = jdbcTemplate.query("select ...");
    Assert.assertEquals(1, records.size());
});

此策略將無限期地重試任何異常,例如您的斷言錯誤。

我的解決方案是使用org.awaitility庫並用返回語句替換斷言:

        await().atMost(30, TimeUnit.SECONDS).until(
            () -> {
                //
                // assertTrue(condition);
                return condition == true;
            }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM