12.5 Asserts
ScalaTest提供了一个简单的assert()
⑤方法。它会检查作为参数的表达式执行结果是否为true
⑥。如果是true
,assert()
方法就会安静地返回;否则它会抛出AssertionError
。下面是一个断言失败的例子:
⑤你还可以导入并使用JUnit、TestNG或是Hamcrest的matcher方法,例如
assertEquals()
和assertThat()
。请务必导入合适的JAR包。⑥
assert()
方法的变体还可以检查参数的执行结果是否为None
。
UnitTestingWithScala/AssertionFailureExample.scala
class AssertionFailureExample extends org.scalatest.Suite {
def testAssertFailure() {
assert(2 == List().size)
}
}
(new AssertionFailureExample).execute()
执行上述测试之后,会得到一个错误信息,如下所示:
Test Starting - Main$$anon$1$AssertionFailureExample.testAssertFailure
TEST FAILED - Main$$anon$1$AssertionFailureExample.testAssertFailure
((virtual file):7)
org.scalatest.TestFailedException:
...
测试结果表示出有错误,但这个消息却没有多大帮助。如果有很多测试,我们会希望得到更多的信息提示,而不仅仅是“某个地方失败了”。ScalaTest提供了===
操作符,与assert()
方法相比,它可以打印出更多的细节信息。例如:
UnitTestingWithScala/AssertionFailureExample2.scala
class AssertionFailureExample2 extends org.scalatest.Suite {
def testAssertFailure() {
assert(2 === List().size)
}
}
(new AssertionFailureExample2).execute()
运行测试之后会得到如下的错误消息:
Test Starting - Main$$anon$1$AssertionFailureExample2.testAssertFailure
TEST FAILED - Main$$anon$1$AssertionFailureExample2.testAssertFailure:
2 did not equal 0 ((virtual file):7)
org.scalatest.TestFailedException: 2 did not equal 0
...
从输出中可以看到,2
不等于0
。这个信息就比前面的assert()
的结果更有帮助。但它还是缺少上下文,如果能知道这些数字到底是什么含义就好了。所幸,我们还可以把一段有意义的消息作为第二个参数传给assert()
方法。
UnitTestingWithScala/AssertionFailureWithMessage.scala
class AssertionFailureWithMessage extends org.scalatest.Suite {
def testAssertFailure() {
assert(2 === List().size, "Unexpected size of List")
}
}
(new AssertionFailureWithMessage).execute()
如果运行上面的代码,就会得到更有意义的信息:
Test Starting - Main$$anon$1$AssertionFailureWithMessage.testAssertFailure
TEST FAILED - Main$$anon$1$AssertionFailureWithMessage.testAssertFailure:
Unexpected size of List
2 did not equal 0 ((virtual file):7)
org.scalatest.TestFailedException: Unexpected size of List
2 did not equal 0
...
如果要检查两个值是否相等(就像JUnit的assertEquals()
方法一样),你就会喜欢上ScalaTest的expect()
方法:
UnitTestingWithScala/ExpectExample.scala
class ExpectExample extends org.scalatest.Suite {
def testAssertFailure() {
expect(2, "Unexpected List size") { List().size }
// The above exception is wrong
}
}
(new ExpectExample).execute()
输出如下:
Test Starting - Main$$anon$1$ExpectExample.testAssertFailure
TEST FAILED - Main$$anon$1$ExpectExample.testAssertFailure:
Unexpected List size
Expected 2, but got 0 ((virtual file):7)
org.scalatest.TestFailedException: Unexpected List size
Expected 2, but got 0
...
expect()
方法接收的是一个期望值,一个可选的消息,一个闭包。闭包里是要执行的表达式,expect()
方法会判断执行结果跟给定的期望值是否相等,如果不相等就会抛出AssertionError
。
expect()
方法既简洁,又容易读懂,还提供了恰到好处的失败信息,所以我更愿意用它来做两个值的比较,而不是用assert()
。