Scalatest是否提供NaN的匹配器?

时间:2019-06-13 08:43:49

标签: scala scalatest matcher

Scalatest是否提供NaN和无穷大的匹配器?

如果可以的话,我想使这些断言更具描述性:

Double.NaN.isNaN shouldBe true
Double.NegativeInfinity.isInfinite shouldBe true

2 个答案:

答案 0 :(得分:6)

处理此问题的最灵活方法可能是使用ScalaTest的support for symbols to handle boolean matches on properties.。因此,以下测试均可正常工作,并在失败时给出非常有用的错误消息:

class DoubleSpec extends FreeSpec with Matchers {

  "NaN should be NaN" in {
    Double.box(Double.NaN) shouldBe 'NaN
  }

  "1 should not be NaN" in {
    Double.box(1d) should not be 'NaN
  }

  "Infinity should be infinite" in {
    Double.box(Double.PositiveInfinity) shouldBe 'Infinite
  }

  "1 should not be infinite" in {
    Double.box(1d) should not be 'Infinite
  }
}

不幸的是,符号支持仅适用于引用类型-需要一个隐式参数T <:< AnyRef。我欢迎提出处理建议,而不必每次都致电Double.box

您也可以为此编写自己的匹配器:

  val NaN : BeMatcher[Double] = (left: Double) => MatchResult(
    left.isNaN,
    s"$left is not NaN",
    s"$left is NaN"
  )

  "NaN should be NaN" in {
    Double.NaN shouldBe NaN
  }

  "1 should not be NaN" in {
    1d should not be NaN
  }

避免装箱问题,并且类型安全性更高,但确实需要一些额外的代码行。

答案 1 :(得分:1)

根据定义,NaN不等于任何值(https://en.wikipedia.org/w/index.php?title=NaN#Comparison_with_NaN)。

基于这个原因,我认为NaN不会存在也不应该存在任何最苛刻的匹配器,因此您最好像现在一样使用.isNaN。

对于无限值,您可以同样使用:

val value = -1.0/0.0
value.isNegInfinity shouldBe true
value.isInfinite shouldBe true
value should equal (Double.NegativeInfinity)