Zio утверждает подтип алгебраического типа данных

Данный алгебраический тип данных

      sealed trait Result
case object Success extends Result
case class MyFailure(details: String) extends Result

Как утверждать в zio-testэто конкретное значение является Failureи его детали содержат определенную подстроку?

Например, как утверждать, что ниже rявляется провалом и с "mana"подстрока?

      val r: Result = MyFailure("not enough mana")

2 ответа

Предполагая, что результат создается эффектом (другими словами, он обернут ZIO), вы можете использовать mapErrorиспользовать detailsв случае неудачи, затем эффективно утверждать, используя assertMа также fails(containsString):

      testM("effectfully") {
  val r = ZIO.fail(MyFailure("not enough mana")).mapError(_.details)
  
  assertM(r.run)(fails(containsString("mana")))
}

это возможно с isCase

отрезать:

      
  /**
   * Makes a new assertion that requires the sum type be a specified term.
   *
   * {{{
   * isCase("Some", Some.unapply, anything)
   * }}}
   */
  def isCase[Sum, Proj](
    termName: String,
    term: Sum => Option[Proj],
    assertion: Assertion[Proj]
  )

И мое (возможно, не идеальное) решение:

      sealed trait Result
case object Success extends Result
case class MyFailure(details: String) extends Result

val r: Result = MyFailure("not enought mana")

test("mana") {
  assert(r)(
    isCase[Result, String](
      "details",
      { 
        case MyFailure(details) => Some(details) 
        case _                  => None
      },
      containsString("mana"))
  )
}

В качестве альтернативы можно создать вспомогательную функцию и использовать ее для таких случаев:

        def matches[A](mf: PartialFunction[A, Boolean]): Assertion[A] =
    Assertion.assertion("matches")() {
      a => mf.orElse[A, Boolean]({ case _ => false })(a)
    }

Теперь тест может выглядеть так:

      assert(r)(
  matches {
    case MyFailure(d) => d.contains("mana")
  }
)
Другие вопросы по тегам