Java - Thread.sleep 与 Awaitility.await()

7

大家好,祝周五愉快! 我希望能用最小的改动将Thread.sleep替换为Awaitility.await(),因为我正在检查一个较旧的存储库中的Sonar错误。我尝试避免使用Awaitility的until功能,但这并不起作用。我知道Awaitility是用于异步行为的,until函数是其中的重要部分。我希望有更多Awaitility经验的人能为我提供在此测试场景中清晰使用它的建议,非常感谢您的贡献。

    //Thread.sleep(1000);
    Awaitility.await().atMost(Duration.ONE_SECOND);
    list = client.getLocation();
    Assertions.assertFalse(list.isEmpty());

如果您不想使用 until,那么最好使用 sleep - Boris the Spider
Boris the Spider先我一步了:如果你有一堆使用Thread.sleep()的代码...并且如果Thread.Sleep有效...那么为什么要改用Awaitility.await()?你的动机/好处是什么?PS:您可能还想考虑这些替代方案:https://www.baeldung.com/java-delay-code-execution - paulsm4
1
@paulsm4 我想替换它以满足 Sonar 规则。 - user2917629
谢谢你说“周五快乐!!!” - KUTAY ZORLU
3个回答

9

尽管您的意图如此,我鼓励您再次尝试使用 Awaitility 和 until()。下面的示例在单个一行代码中测试相同的内容(尽管为了提高可读性而编写为多行):

@Test
void test_refresh() {
    Awaitility
       .await()
       .atMost(5, TimeUnit.SECONDS)
       .until(() -> { 
           List<Trp> trpList = client.getAllTrps();
           return !trpList.isEmpty();
       });
}

如果您想要更细致地控制轮询,可以查看像pollInterval()pollDelay()这样的方法。


根据OP的更新,这似乎是一个XYProblem。问题并不是真正的“Thread.sleep()”,解决方案也不一定是“Awaitility.await()”。真正的问题是Sonar在抱怨“Thread.sleep()”。 - paulsm4
我喜欢你的解决方案,它还解决了for循环的问题,非常感谢你的输入,我非常感激。 - user2917629
1
@paulsm4 感谢您的评论。我猜测这是导致问题的声纳警告:https://rules.sonarsource.com/java/RSPEC-2925,它提到`Awaitility.await().atMost().until()`作为可能的解决方案。 - matsev

6

虽然你所做的事情一开始看起来有道理,但更深入地了解库的设计后,你忽略了两个明显的原则。

Awaitility库引入了函数式样式的用法来定义属性、条件、累加器和转换。

1. 终端操作。


  Awaitility
       .await()
       .atMost(Duration.TWO_SECONDS)

以上的代码将不会执行,因为内部运行链的调用是通过调用ConditionFactory#until才能访问到Condition#await

until的调用可以称为终端操作

2. 中间操作。


awaitatMosttimeout和其他操作只返回ConditionFactory的同一实例,这个实例只会以一种惰性的方式定义行为和动作。

所以简而言之,该设计期望您:

  1. 使用Awaitility#await创建ConditionFactory的一个实例。
  2. 使用中间方法定义等待行为。
  3. 使用until及其变体执行和/或转换。

1
使用Awaitility进行简单替换:
Thread.sleep(200);

可能是:

Awaitility.await()
      .pollDelay(Duration.ofMillis(200))
      .until(() -> true);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接