Operations
Logical Operations
What is really useful in assertions is that they behave like boolean values and can be composed with operators known from operating on boolean values like and (&&
), or (||
), negation (negate
):
import zio.test.Assertion
val assertionForString: Assertion[String] =
Assertion.containsString("Foo") && Assertion.endsWithString("Bar")
Composable Nested Assertions
Assertions also compose with each other allowing for doing rich diffs not only simple value to value comparison:
import zio.test._
import zio.test.Assertion.{isRight, isSome, equalTo, hasField}
test("Check assertions") {
assert(Right(Some(2)))(isRight(isSome(equalTo(2))))
}
Here we're checking deeply nested values inside an Either
and Option
. Because Assertion
s compose this is not a problem. All layers are being peeled off tested for the condition until the final value is reached.
Here the expression Right(Some(2))
is of type Either[Any, Option[Int]]
and our assertion isRight(isSome(equalTo(2)))
is of type Assertion[Either[Any, Option[Int]]]