3.3 测试实现标准的ZIO服务

编程入门 行业动态 更新时间:2024-10-28 18:26:32

3.3 <a href=https://www.elefans.com/category/jswz/34/1771117.html style=测试实现标准的ZIO服务"/>

3.3 测试实现标准的ZIO服务

3.3 测试实现标准的ZIO服务

我们测试ZIO程序时,我们遇到的常见问题之一就是使用ZIO的标准服务来测试effect。
例如,考虑这个简单的控制台程序。

  import zio.console._val greet: ZIO[Console, Nothing, Unit] = for {name <- getStrLn.orDie_ <- putStrLn(s"Hello, $name!")} yield ()// greet: ZIO[Console, Nothing, Unit] = zio.ZIO$FlatMap@61f0affd

这是一个非常简单的程序,我们相信它是正确的,但是我们将如何对其进行测试?
我们可以自己运行程序并验证是否收到了预期的控制台输出,但这是非常手动的,并且可能导致对潜在的控制台输入的测试覆盖面非常小,并且随着代码库其他部分的更改而缺乏持续集成。
所以我们不想这样做。 但是我们还要如何测试呢?
getStrLn将要从控制台读取实际的行,而putStrLn将要向控制台打印实际的行,那么我们如何提供输入并验证输出正确而不实际自己做呢?

这就是控制台是环境中的一项服务的事实。 因为Console是一项服务,所以我们可以提供另一种测试实现,例如,它从已填充了适当输入的输入缓冲区“读取”行,并将行“写入”到我们可以检查的输出缓冲区。
ZIO Test就是这样做的,它提供了所有标准ZIO服务的TestConsole,TestClock,TestRandom和TestSystem实现,这些服务完全确定性地有助于测试。
ZIO Test将自动为我们的每个测试提供这些服务的副本,这使此操作极为容易。 通常,我们需要做的就是调用几个特定的“测试”方法来提供所需的输入并验证输出。
为此,让我们看一下如何测试上面的控制台程序。

  import zio.test.environment._object ExampleSpec extends DefaultRunnableSpec {def spec = suite("ExampleSpec")(testM("greet says hello to the user") {for {_ <- TestConsole.feedLines("Jane")_ <- greetvalue <- TestConsole.output} yield assert(value)(equalTo(Vector("Hello, Jane!\n")))})}

我们现在已经从根本无法测试的程序变成了完全可以测试的程序。现在,我们甚至可以使用ZIO
Test对下面所述的基于属性的测试的支持来提供各种不同的输入,并将其包括在我们的持续集成过程中,以在此处获得很高的测试覆盖率。
请注意,每个服务都会自动为每个测试提供单独的副本,因此您在使用这些测试服务时不必担心测试之间的干扰。
对于测试并发程序特别有用的另一个测试服务是TestClock。正如在上一章中所看到的,我们通常希望将事件安排在某个指定的持续时间之后发生,例如,在一个小时内进行goShopping,并且我们想验证事件是否确实在指定的持续时间之后发生。
同样,我们面临测试的问题。我们是否需要等待一个小时,以便goShopping执行以验证其是否已正确调度?

No! TestClock允许我们确定性地测试涉及时间的效果,而无需等待实时时间过去。
这是我们可以使用TestClock测试延迟指定时间的方法的方法。

  import zio.clock._ import zio.duration._val goShopping: ZIO[Console with Clock, Nothing, Unit] = putStrLn("Going shopping!").delay(1.hour)// goShopping: ZIO[Console with Clock, Nothing, Unit] = zio.ZIO$FlatMap@7be0b150object ExampleSpec extends DefaultRunnableSpec {def spec = suite("ExampleSpec")( testM("goShopping delays for one hour") {for {fiber <- goShopping.fork_ <- TestClock.adjust(1.hour)_ <- fiber.join} yield assertCompletes }) }

我们在这里用fork和join操作介绍了几个新概念,我们将在后面几章中更全面地了解这些概念,但是在这里fork是将goShopping作为单独的逻辑过程开始执行,而主程序流程继续进行。而
join 会等待该过程完成。
由于使用的Clock实现是TestClock,因此只有在用户通过调用诸如Adjust之类的运算符进行调整时,时间才会过去。
在这里Adjust(1.hour)使所有计划在一小时或更短时间内运行的效果立即按顺序运行,从而导致goShopping完成执行并允许程序终止。
我们在这里使用assertCompletes(这是一个始终满足的断言)来更清楚地表达我们的意图,即我们在此处测试的只是该程序已完全完成。

更多推荐

3.3 测试实现标准的ZIO服务

本文发布于:2023-07-03 16:28:06,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1008947.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:测试   标准   ZIO

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!