Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does one assert a single field in error type?

Let's assume I have code such as this:

final case class CustomException(errorCode: Int, id: UUID) extends Throwable

val logic: ZIO[Any, Throwable, Unit] = ???

I would like to use ZIO Test to check for a specific error case

val checkForTimeout = testM("Logic should time out") {
  for {
    result <- logic.flip
  } yield assert(result, isSubtype[CustomException](???))
}

What I would like to do is check the errorCode field for a specific value. But it seems the existing combinators in ZIO Test only allow me to check the the full object. I would like to only check for _.errorCode while ignoring _.id, which means equalTo is not a good enough combinator for this use case.

How would I go about addressing this?

like image 772
Tim Steinbach Avatar asked Nov 28 '25 20:11

Tim Steinbach


2 Answers

You can use Assertion.hasField, which lets you "zoom in" on one part of a larger structure, to do this.

val checkForTimeout = testM("Logic should time out") {
  for {
    result <- logic.flip
  } yield assert(
      result,
      isSubtype[CustomException](hasField("errorCode", _.errorCode, equalTo(1)))
    )
}
like image 79
Adam Fraser Avatar answered Dec 01 '25 10:12

Adam Fraser


The simplest thing would be to adjust the signature of logic.

val logic: ZIO[Any, CustomException, Unit] = ???

Now you can do something like:

val checkForTimeout = testM("Logic should time out") {
    for {
      result: CustomException <- logic.flip
    } yield assert(result.errorCode, equalTo(543))
}

If not you can still cast the result:

val checkForTimeout = testM("Logic should time out") {
    for {
      th <- logic.flip
      result = th.asInstanceOf[CustomException]
    } yield assert(result.errorCode, equalTo(543))
}
like image 42
pme Avatar answered Dec 01 '25 10:12

pme