12.5 Asserts

ScalaTest提供了一个简单的assert()⑤方法。它会检查作为参数的表达式执行结果是否为true⑥。如果是trueassert()方法就会安静地返回;否则它会抛出AssertionError。下面是一个断言失败的例子:

⑤你还可以导入并使用JUnit、TestNG或是Hamcrest的matcher方法,例如assertEquals()assertThat()。请务必导入合适的JAR包。

assert()方法的变体还可以检查参数的执行结果是否为None


UnitTestingWithScala/AssertionFailureExample.scala

  1. class AssertionFailureExample extends org.scalatest.Suite {
  2. def testAssertFailure() {
  3. assert(2 == List().size)
  4. }
  5. }
  6. (new AssertionFailureExample).execute()

执行上述测试之后,会得到一个错误信息,如下所示:

  1. Test Starting - Main$$anon$1$AssertionFailureExample.testAssertFailure
  2. TEST FAILED - Main$$anon$1$AssertionFailureExample.testAssertFailure
  3. ((virtual file):7)
  4. org.scalatest.TestFailedException:
  5. ...

测试结果表示出有错误,但这个消息却没有多大帮助。如果有很多测试,我们会希望得到更多的信息提示,而不仅仅是“某个地方失败了”。ScalaTest提供了===操作符,与assert()方法相比,它可以打印出更多的细节信息。例如:

UnitTestingWithScala/AssertionFailureExample2.scala

  1. class AssertionFailureExample2 extends org.scalatest.Suite {
  2. def testAssertFailure() {
  3. assert(2 === List().size)
  4. }
  5. }
  6. (new AssertionFailureExample2).execute()

运行测试之后会得到如下的错误消息:

  1. Test Starting - Main$$anon$1$AssertionFailureExample2.testAssertFailure
  2. TEST FAILED - Main$$anon$1$AssertionFailureExample2.testAssertFailure:
  3. 2 did not equal 0 ((virtual file):7)
  4. org.scalatest.TestFailedException: 2 did not equal 0
  5. ...

从输出中可以看到,2不等于0。这个信息就比前面的assert()的结果更有帮助。但它还是缺少上下文,如果能知道这些数字到底是什么含义就好了。所幸,我们还可以把一段有意义的消息作为第二个参数传给assert()方法。

UnitTestingWithScala/AssertionFailureWithMessage.scala

  1. class AssertionFailureWithMessage extends org.scalatest.Suite {
  2. def testAssertFailure() {
  3. assert(2 === List().size, "Unexpected size of List")
  4. }
  5. }
  6. (new AssertionFailureWithMessage).execute()

如果运行上面的代码,就会得到更有意义的信息:

  1. Test Starting - Main$$anon$1$AssertionFailureWithMessage.testAssertFailure
  2. TEST FAILED - Main$$anon$1$AssertionFailureWithMessage.testAssertFailure:
  3. Unexpected size of List
  4. 2 did not equal 0 ((virtual file):7)
  5. org.scalatest.TestFailedException: Unexpected size of List
  6. 2 did not equal 0
  7. ...

如果要检查两个值是否相等(就像JUnit的assertEquals()方法一样),你就会喜欢上ScalaTest的expect()方法:

UnitTestingWithScala/ExpectExample.scala

  1. class ExpectExample extends org.scalatest.Suite {
  2. def testAssertFailure() {
  3. expect(2, "Unexpected List size") { List().size }
  4. // The above exception is wrong
  5. }
  6. }
  7. (new ExpectExample).execute()

输出如下:

  1. Test Starting - Main$$anon$1$ExpectExample.testAssertFailure
  2. TEST FAILED - Main$$anon$1$ExpectExample.testAssertFailure:
  3. Unexpected List size
  4. Expected 2, but got 0 ((virtual file):7)
  5. org.scalatest.TestFailedException: Unexpected List size
  6. Expected 2, but got 0
  7. ...

expect()方法接收的是一个期望值,一个可选的消息,一个闭包。闭包里是要执行的表达式,expect()方法会判断执行结果跟给定的期望值是否相等,如果不相等就会抛出AssertionError

expect()方法既简洁,又容易读懂,还提供了恰到好处的失败信息,所以我更愿意用它来做两个值的比较,而不是用assert()