如何使用ZIO 2与zio-test断言效果的失败场景?
测试ZIO 2效果失败场景的正确方式
首先,你的validate方法存在两处需要修正的问题:
- 有效ID分支缺少成功返回值,需补充
ZIO.unit ZIO.fail的参数必须是Throwable类型,不能直接传字符串,要包装成异常
修正后的方法:
def validate(id: String): ZIO[Any, Throwable, Unit] = { if (id == "invalid-id") { ZIO.fail(new RuntimeException("Invalid id")) } else { ZIO.unit } }
为什么你的测试代码无法编译?
当validate("invalid-id")执行失败时,ZIO的for推导式会直接终止流程,根本不会走到yield步骤,所以result变量不会被赋值,isFailure(result)自然无法通过编译。
正确的测试方式
方式一:用assertZIO结合fails断言(推荐)
ZIO Test提供了专门的断言工具来测试效果的失败状态,直接对整个ZIO效果做断言:
import zio.test._ import zio.test.Assertion._ suite("My suite")( test("When id is valid") { assertZIO(validate("valid-id"))(equalTo(())) }, test("When id is not valid") { // 断言效果会失败,且错误信息符合预期 assertZIO(validate("invalid-id"))(fails(hasMessage(equalTo("Invalid id")))) } )
方式二:手动捕获失败并断言
如果你想手动处理失败流程,可以用catchAll捕获错误后再做断言:
test("When id is not valid") { validate("invalid-id").catchAll { error => assertTrue(error.getMessage == "Invalid id") } }
额外说明
fails断言可以配合其他断言组合使用,比如hasType校验异常类型:fails(hasType[RuntimeException])- 建议将
zio和zio-test版本统一(你当前zio是2.0.4,zio-test是2.0.5),避免潜在兼容性问题
内容的提问来源于stack exchange,提问作者elarous
相关产品推荐
相关产品推荐

