Home > Software design >  Assert a failed effect with ZIO2 and zio-test
Assert a failed effect with ZIO2 and zio-test

Time:12-22

I am a beginner in the Scala / ZIO 2 world, and I am trying to write some tests for a simple service.

so I have this method:

def validate(id: String): ZIO[Any, Throwable, Unit] = {
  if (id == "invalid-id") {
    ZIO.fail("Invalid id")
  }
}

I tried several things, but mainly I tried to use the isFailure or the fails assertions:

 suite("My suite")(
    test("When id is valid") { // This passes
      for {
        result <- validate("valid-id")
      } yield assertTrue(result == ())
    },
    test("when id is not valid") { 
      for {
        result <- validate("invalid-id")
      } yield assertTrue(isFailure(result)) // This doesn't even compile
    }
  )

How can I test the failure case of an effect?

I am using:

Scala: "3.2.1"
zio: "2.0.4"
zio-test: "2.0.5"

CodePudding user response:

There are multiple ways to assert that an effect has failed. The below example demonstrates the use of ZIO#exit and ZIO#flip.

import zio._
import zio.test._

object MySpec extends ZIOSpecDefault {

  def validate(id: String): ZIO[Any, String, Unit] =
    ZIO.cond(id != "invalid-id", (), "Invalid id")

  def spec =
    suite("My suite")(

      test("when id is not valid 1") {
        for {
          result <- validate("invalid-id").exit
        } yield assertTrue(
          result == Exit.fail("Invalid id")
        )
      },

      test("when id is not valid 2") {
        for {
          result <- validate("invalid-id").flip
        } yield assertTrue(
          result == "Invalid id"
        )
      }
    )
}

CodePudding user response:

To test the failure case of an effect, you can use the assertM method from zio-test, which allows you to specify a matcher for the effect's failure. Here's an example of how you can use it:

import zio.test._
import zio.test.Assertion._

suite("My suite")(
  test("When id is valid") {
    for {
      result <- validate("valid-id")
    } yield assertTrue(result == ())
  },
  test("when id is not valid") {
    for {
      result <- validate("invalid-id")
    } yield assertM(result)(fails(isSubtype[Throwable](classOf[Throwable])))
  }
)

In this example, we are using the fails matcher from zio-test to assert that the effect fails with a Throwable or a subtype of Throwable. You can also use the failsWith matcher to assert that the effect fails with a specific error message or exception type.

For example:

assertM(result)(failsWith("Invalid id"))

This will assert that the effect fails with the error message "Invalid id".

  • Related