如何在Scala测试中检查“Either”结果?

hgqdbh6s  于 2023-01-17  发布在  Scala
关注(0)|答案(4)|浏览(177)

我对Scala测试比较陌生,所以我咨询了documentation如何测试Either值。
我试着像这样复制指令:

import org.scalatest.EitherValues
import org.scalatest.flatspec.AnyFlatSpec

class EitherTest extends AnyFlatSpec with EitherValues {
  val either: Either[Exception, Int] = Right(42)

  either.right.value should be > 1
}

这个实现不起作用,我得到了一个语法错误。我做错了什么?
错误:
错误:(9,22)值不应该是Int的成员。正确。值应该大于1错误:(9,29)未找到:值可以是.正确.值应该〉1-Hannes 14小时前

piok6c0g

piok6c0g1#

通过匹配模式来测试Either更具可读性,ScalaTest的Inside特性允许您在模式匹配后进行Assert。

import org.scalatest.Inside
import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should.Matchers

class EitherTest extends AnyFlatSpec with Inside with Matchers {
  val either: Either[Exception, Int] = Right(42)

  either should matchPattern { case Right(42) => }

  inside(either) { case Right(n) =>
    n should be > 1
  }

  val either2: Either[Exception, Int] = Left(new Exception("Bad argument"))

  inside(either2) { case Left(e) =>
    e.getMessage should startWith ("Bad")
  }

}
vxqlmq5t

vxqlmq5t2#

有一个开放的拉取请求Add EitherValuable #1712,目的是解决Scala 2.13中RightProjection被弃用的问题:
目前,.right已被弃用(我相信它将保持这种状态),但.left还没有被弃用,就像scala/scala#8012一样
在将来的ScalaTest版本中,EitherValues的新语法可能会变为rightValueleftValue,如下所示

either.rightValue should be > 1
wwodge7n

wwodge7n3#

我会这么做。
首先检查它是否正确,然后比较值:

either.isRight shouldBe true
either.getOrElse(0) shouldBe 42

另一种方法是在不正确的情况下失败:

either.getOrElse(fail("either was not Right!")) shouldBe 42

我还将 Package 您的测试,例如 * WordSpec *:

"My Either" should {
  "be Right" in {
    either.getOrElse(fail("either was not Right!")) shouldBe 42
  }
}

这会提示你问题出在哪里。否则,如果它失败了,你得到的只是一个讨厌的错误堆栈。
整个例子如下:

class EitherTest
  extends WordSpec
  with Matchers
  with EitherValues {

  // val either: Either[Exception, Int] = Right(42)
  val either: Either[Exception, Int] = Left(new IllegalArgumentException)
  "My Either" should {
    "be Right" in {
      either.getOrElse(fail("either was not Right!")) shouldBe 42
    }
  }
}
2w3rbyxf

2w3rbyxf4#

您是否考虑过inside特性?这样您就可以使用模式匹配来测试Either中的值。例如:

import org.scalatest.Inside.inside
...
val result = FooBarInputValidator(value)
inside(result) { case Left(validationError) => 
   validationError.message shouldBe "Invalid input"
   validationError.parameter shouldBe "FooBar"
}

相关问题