在 Scalatest 3.0.5 中,方法 shouldBe
将等式检查委托给方法 areEqualComparingArraysStructurally
:
def shouldBe(right: Any): Assertion = {
if (!areEqualComparingArraysStructurally(leftSideValue, right)) {
val (leftee, rightee) = Suite.getObjectsForFailureMessage(leftSideValue, right)
val localPrettifier = prettifier
indicateFailure(FailureMessages.wasNotEqualTo(localPrettifier, leftee, rightee), None, pos)
}
else indicateSuccess(FailureMessages.wasEqualTo(prettifier, leftSideValue, right))
}
这将简单地将相等性检查(正如你所期望的)委派给 ==
运算符:
private[scalatest] def areEqualComparingArraysStructurally(left: Any, right: Any): Boolean = {
left match {
case leftArray: Array[_] =>
right match {
case rightArray: Array[_] => leftArray.deep == rightArray.deep
case _ => leftArray.deep == right
}
case _ => {
right match {
case rightArray: Array[_] => left == rightArray.deep
case _ => left == right
}
}
}
}
在Scala中,至少在JVM上,
==
只是调用
equals
方法,如果没有被覆盖,则检查比较的变量是否指向同一个对象。
case class
是特殊的,因为编译器会为你覆盖
equals
方法以比较构造函数的参数。
您可以使用以下代码轻松测试它(但是您可以想象,对于自己使用
==
也是一样的):
package org.example
import org.scalatest.{FlatSpec, Matchers}
final class MyClass(val a: Int)
final case class MyCaseClass(a: Int)
final class TestSpec extends FlatSpec with Matchers {
"equality on case classes" should "succeed" in {
new MyCaseClass(1) shouldBe new MyCaseClass(1)
}
"equality on non-case classes" should "fail" in {
new MyClass(1) shouldNot be(new MyClass(1))
}
"equality between Regex objects" should "fail" in {
"abc".r shouldNot be("abc".r)
}
}
r
方法所做的是实例化一个新的 Regex
对象,这不是一个 case class
并且也没有覆盖等式定义,因此导致了您看到的结果。
"abc".r == "abc".r
也是false,因此它不是特定于scalatest的。 - joel