【问题标题】:How to check an "Either" result in Scala Test?如何在 Scala 测试中检查“任一”结果?
【发布时间】:2020-04-13 20:42:55
【问题描述】:

我对 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 的成员。right.value 应该 > 1 错误:(9, 29) not found: value be either.right.value 应该 > 1 – Hannes 14 小时前

【问题讨论】:

  • 你得到的错误是什么?你能补充一下吗
  • Error:(9, 22) value should is not a member of Int either.right.value should be > 1 Error:(9, 29) not found: value be either.right.value should be > 1
  • 您可以尝试从 Either 中删除显式类型签名,看看是否可行? val either = Right(42)
  • @Hannes:我认为你错过了Matchers 的混音(例如class EitherTest extends AnyFlatSpec with EitherValues with Matchers)。
  • @Marth mix-in org.scalatest.matchers.should.Matchers 摆脱了语法错误,但我的 IDE 仍然声明 Either.right 自 Scala 2.13.0 以来已弃用,这是预期的吗?

标签: scala scalatest


【解决方案1】:

测试通过匹配模式可以更具可读性。 ScalaTest 的Inside trait 允许您在模式匹配后进行断言。

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

}

【讨论】:

  • 谢谢sn-p这个代码,我试试看!但我有两个问题:1)=> } 语法是什么?我知道匹配语法,但我不知道您可以省略表达式的正确部分。 2)matchPattern可以和"Either" should matchPattern in { ...}语法一起使用吗?
  • @Hannes 1. 右侧为空单元,没有任何实现。我们只检查与模式匹配的任何一个。 2. Scalatest 文档scalatest.org/user_guide/using_matchers#matchingAPattern中关于匹配模式的更多细节@
【解决方案2】:

有一个开放的拉取请求 Add EitherValuable #1712 旨在解决在 Scala 2.13 中 RightProjectiondeprecated 的事实:

目前.right 已被弃用(我相信它会保持这种状态) 但.left 不是,根据scala/scala#8012

未来 ScalaTest 版本中 EitherValues 的新语法可能会变成 rightValueleftValue 就像这样

either.rightValue should be > 1

【讨论】:

    【解决方案3】:

    我会这样做。

    先检查是否正确,然后比较值:

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

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

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

    我也会包装你的测试,例如 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
        }
      }
    }
    

    【讨论】:

    • shouldBe 似乎不存在。我还需要其他混音吗?
    • 我想你错过了with Matchers 看到我更新的答案
    猜你喜欢
    • 2018-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-07
    • 2012-01-23
    • 1970-01-01
    相关资源
    最近更新 更多