ZIO 不允许通过重试 Schedule.exponential 来测试效果

问题描述 投票:0回答:1

第一次重复后测试就挂起

  test("test retry exponential") {
    for {
      _ <- TestClock.adjust(10.milliseconds)
      res <- ZIO.fail("fail").retry(Schedule.exponential(10.milliseconds) && 
         Schedule.recurs(3).tapOutput(o => ZIO.logInfo(s"retrying $o")))
    } yield assertTrue(res == null)
}

当我仅使用 Schedule.recurs 时它可以工作

scala zio zio-test
1个回答
0
投票

TestClock 不会提前时间,除非你告诉它。 这里是关于如何提前测试时间的文档

Schedule.recurs 没有时间部分,它只执行 3 次。 intersection 组合器的工作原理与布尔表达式相同。如果两个计划都准备好再次运行,则合并的计划就准备好运行。如果左或右时间表尚未准备好,则合并的时间表尚未准备好。由于您的测试当前不会提前时间,因此效果第一次失败后永远不会过去 10 毫秒,因此该计划将永远无法准备好再次运行。

作为旁注,这个断言:

test("should fail") {
    for {
        res <- ZIO.fail("BOOM!")
    } yield ??? // assert that effect failed
}

...更好地表达如下:

test("should fail") {
    for {
        exit <- ZIO.fail("BOOM!").exit
    } yield assert(exit)(Assertion.fails(Assertion.equalTo("BOOM!"))
}

为了测试失败,需要调用效果的退出方法。这为您提供了一个 Exit,它有点像具有成功或失败值的 Either,您可以在测试中检查并断言它。

assert 方法采用第一个参数列表中的值,第二个参数列表采用 Assertion[T],其中 T 是值的类型。如您所见,您可以编写这些断言。 Assertion.fails 采用一个新的 Assertion[T],其中 T 现在是效果失败的值,在我们的例子中是字符串,在另一个测试用例中可能是 Throwable。

有时我们不想测试每一个细节,所以有像 Assertion.anything 这样的断言。 Assertion.fails(Assertion.anything) 可能足以满足您的特定情况。还有一种称为assertCompletes,它是典型虚拟断言(如assert true == true)的一种更具描述性的方式。

阅读更多这里

© www.soinside.com 2019 - 2024. All rights reserved.