scalaziozio-test

How to test an exception case with zio-test


I have the following function, that I want to test:

def people(id: Int): RIO[R, People]

This function returns People if there is one for that id, resp. fails if not, like:

IO.fail(ServiceException(s"No People with id $id"))

The happy case works, like:

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()))
    },

But how can I test the failure case? I tried different things, mostly the types do not match. Here is an attempt:

    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")))
    }
  )

Solution

  • I think you've definitely got it. The only thing I would add for others with similar questions is your example also involves an environment type, which is a great topic for discussion but somewhat independent of how to test that an effect fails as expected using ZIO Test.

    I've included below a minimal example of how to test that an effect fails as expected. As mentioned above, you would call run on the effect to get an exit value and then use Assertion.fails to assert that the effect fails with a checked exception, Assertion.dies to assert that the effect fails with an unchecked exception, or Assertion.interrupted to test that an effect was interrupted.

    Also note that you do not have to use include equalTo("fail"). If all you care about is that the effect failed you can just use fails(anything). If you are testing that an effect dies with a specified exception you can do something like dies(isSubtype[IllegalArgumentException]).

    Hope this helps!

    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")))
            }
          )
        )