ZIO: Как протестировать исключительный случай с помощью zio-test - PullRequest
1 голос
/ 01 ноября 2019

У меня есть следующая функция, которую я хочу протестировать:

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

Эта функция возвращает людей, если есть такая для id, соответственно. не работает, если нет, например:

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

Счастливый случай работает, например:

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

Но как я могу проверить случай отказа? Я пробовал разные вещи, в основном типы не совпадают. Вот попытка:

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

Ответы [ 3 ]

3 голосов
/ 02 ноября 2019

Я думаю, вы определенно поняли. Единственное, что я хотел бы добавить для других с похожими вопросами, это то, что в вашем примере также используется тип среды, который является отличной темой для обсуждения, но в какой-то степени независим от того, как проверить, что эффект дает сбой, как и ожидалось, с помощью теста ZIO.

Я включил ниже минимальный пример того, как проверить, что эффект терпит неудачу, как ожидалось. Как упомянуто выше, вы вызываете run для эффекта, чтобы получить значение выхода, а затем используете Assertion.fails, чтобы утверждать, что эффект завершается неудачей с проверенным исключением, Assertion.dies, чтобы утверждать, что эффект завершается неудачей с непроверенным исключением, илиAssertion.interrupted для проверки того, что эффект был прерван.

Также обратите внимание, что вам не нужно использовать include equalTo("fail"). Если вас беспокоит только то, что эффект не удался, вы можете просто использовать fails(anything). Если вы проверяете, что эффект умирает с указанным исключением, вы можете сделать что-то вроде dies(isSubtype[IllegalArgumentException]).

Надеюсь, это поможет!

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")))
        }
      )
    )
2 голосов
/ 01 ноября 2019

С помощью @adamfraser в ZIO-Chat :

В основном вызовите запуск по вашему неэффективному эффекту и затем подтвердите, что этоошибка с Assertion.fails. Или Assertion.dies, если это непроверенное исключение.

Мне кажется, у меня теперь есть хорошее решение.

testM("get not existing People") {
    for {
      peopleRef <- Ref.make(Vector(People()))
      failure <- Swapi.>.people(2).provide(Test(peopleRef)).run
    } yield assert(
      failure,
      fails(equalTo(ServiceException("No People with id 2")))
    )
  }

Другие решения по-прежнему приветствуются.

1 голос
/ 12 ноября 2019

Вы также можете переключать каналы ошибок и результатов:

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").flip
          } yield assert(result, equalTo("fail"))
        }
      )
    )
...