pme*_*pme 4 scala zio zio-test
我有以下功能,我想测试:
def people(id: Int): RIO[R, People]
Run Code Online (Sandbox Code Playgroud)
如果有一个,这个函数会返回 People id,resp。如果不是,则失败,例如:
IO.fail(ServiceException(s"No People with id $id"))
Run Code Online (Sandbox Code Playgroud)
快乐的案例有效,例如:
suite("Get a Person for an ID") (
testM("get Luke Skywalker") {
for {
peopleRef <- Ref.make(Vector(People()))
luke <- Swapi.>.people(1).provide(Test(peopleRef))
} yield assert(luke, equalTo(People()))
},
Run Code Online (Sandbox Code Playgroud)
但是我如何测试失败案例呢?我尝试了不同的东西,主要是类型不匹配。这是一个尝试:
testM("get not existing People") {
(for {
peopleRef <- Ref.make(Vector(People()))
failure = Swapi.>.people(2).provide(Test(peopleRef))
} yield assertM(failure, fail(Cause.die(ServiceException(s"No People with id 2")))
}
)
Run Code Online (Sandbox Code Playgroud)
这是用于assertMZIO 1.0 的另一个紧凑变体:
import zio._
import zio.test.Assertion.{equalTo, fails}
import zio.test._
object ExampleSpec extends DefaultRunnableSpec {
def spec = suite("ExampleSpec")(
testM("Example of testing for expected failure") {
assertM(ZIO.fail("fail").run)(fails(equalTo("fail")))
}
)
}
Run Code Online (Sandbox Code Playgroud)
在 ZIO 2.0 中,测试看起来非常相似:
import zio._
import zio.test._
import zio.test.Assertion.{equalTo, fails}
object ExampleSpec extends ZIOSpecDefault {
def spec = suite("ExampleSpec ZIO 2.0")(
test("Example of testing for expected failure in ZIO 2.0") {
assertZIO(ZIO.fail("fail").exit)(fails(equalTo("fail")))
}
)
}
Run Code Online (Sandbox Code Playgroud)
ZIO 2.0有一些变化:
exit而不是runtest而不是testMassert有一个新的柯里化语法assert(result)(assertion)import zio.test._
import zio.test.Assertion._
import zio.ZIO
object ExampleSpec extends DefaultRunnableSpec(
suite("ExampleSpec")(
test("Example of testing for expected failure") {
for {
result <- ZIO.fail("failureResult").exit
} yield assert(result)(
fails(equalTo("failureResult"))
)
}
)
)
Run Code Online (Sandbox Code Playgroud)
我想你肯定明白了。我唯一要为其他有类似问题的人补充的是,您的示例还涉及环境类型,这是一个很好的讨论主题,但与如何使用 ZIO Test 测试效果是否按预期失败有关。
我在下面包含了一个如何测试效果是否按预期失败的最小示例。如上所述,您可以调用run效果来获取退出值,然后使用它Assertion.fails来断言效果因已检查异常而失败、因未检查异常Assertion.dies而断言效果失败,或Assertion.interrupted测试效果是否已中断。
另请注意,您不必使用 include equalTo("fail")。如果您只关心效果失败,您可以使用fails(anything). 如果您正在测试某个效果是否因指定的异常而消失,您可以执行类似dies(isSubtype[IllegalArgumentException]).
希望这可以帮助!
import zio.test._
import zio.test.Assertion._
import zio.ZIO
object ExampleSpec
extends DefaultRunnableSpec(
suite("ExampleSpec")(
testM("Example of testing for expected failure") {
for {
result <- ZIO.fail("fail")
} yield assert(result, fails(equalTo("fail")))
}
)
)
Run Code Online (Sandbox Code Playgroud)
如果您的错误是可抛出的,equalsTo则当它针对正在运行的效果运行时会失败,因此您必须使用isSubtype断言来检查您是否收到正确的错误,这有点棘手:
import zio.test._
import zio.test.Assertion._
import zio.ZIO
object ExampleSpec
extends DefaultRunnableSpec(
suite("ExampleSpec")(
testM("Example of testing for expected failure") {
for {
result <- ZIO.fail(new NoSuchElementException).run
} yield assert(result, fails(isSubtype[NoSuchElementException](anything)))
}
)
)
Run Code Online (Sandbox Code Playgroud)
在ZIO-Chat中@adamfraser 的帮助下:
基本上调用 run 失败的效果,然后断言它是 Assertion.fails 的失败。或者 Assertion.dies 如果它是一个未经检查的异常。
我想我现在有一个很好的解决方案。
testM("get not existing People") {
for {
peopleRef <- Ref.make(Vector(People()))
failure <- Swapi.>.people(2).provide(Test(peopleRef)).run
} yield assert(
failure,
fails(equalTo(ServiceException("No People with id 2")))
)
}
Run Code Online (Sandbox Code Playgroud)
仍然欢迎其他解决方案。
您还可以翻转错误和结果通道:
import zio.test._
import zio.test.Assertion._
import zio.ZIO
object ExampleSpec
extends DefaultRunnableSpec(
suite("ExampleSpec")(
testM("Example of testing for expected failure") {
for {
result <- ZIO.fail("fail").flip
} yield assert(result, equalTo("fail"))
}
)
)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1664 次 |
| 最近记录: |