ScalaTest 108: How to test expected exceptions with ‘intercept’

Problem: Using ScalaTest, you want to test a portion of your code that should throw an exception under certain conditions.

Solution

Use the intercept method to verify the exception occurs. In the following example, the boom method will always throw an exception. The intercept method lets you catch that exception, so you can verify that this portion of the method works as desired:

test ("catching an exception") {
  val thrown = intercept[Exception] {
    pizza.boom
  }
  assert(thrown.getMessage === "Boom!")
}

Here’s how this code works:

  • If boom throws an exception, intercept will catch and return that exception. This lets you assign it to a variable like thrown.
  • If boom completes normally, or throws an exception you weren’t expecting, intercept will complete abruptly with a TestFailedException.

As shown, you catch the exception in a value named something like thrown, and then test the message from the exception inside an assert method.

Discussion

This example used intercept to catch the exception, and assert to test the exception message, but this isn’t the only possible solution.

The following code shows that you don’t have to catch the exception as an object and then test its message. Because intercept will end the test with a TestFailedException if your code doesn’t throw an exception, your test can be as simple as this:

test ("catching an exception") {
  intercept[Exception] { pizza.boom }
}

If your code throws the exception, intercept catches it, and the test succeeds. (You expected it to throw an exception, and it did.)

Conversely, if your method doesn’t throw an exception, intercept will make the test fail. The output looks like this:

[info] - catching an exception *** FAILED ***
[info]   Expected exception java.lang.Exception to be thrown, 
         but no exception was thrown. (Test.scala:27)

Of course, you can also use a try/catch block to test that the exception occurs under the right situations, but intercept was created as a way to assist with this common testing pattern.

See Also