Unit Tests: How to test for Exceptions

Permanent Link: Unit Tests: How to test for Exceptions 3. April 2009 RSS Feed for comments on RSS-Feed für Kommentare zu: Unit Tests: How to test for Exceptions comments feed

When unit testing, you'd also want to test whether your application throws Exceptions as expected (the following examples are based on SimpleTest). Assumption for the examples is, that we have a method that expects an integer as parameter.

First way you probably come up with is this:

try {
$class->method('abc');
} catch(Exception $e) {
$this->assertIsA('Exception', $e);
}

Generally this looks ok, but it's not. If the method doesn't throw an exception, the test won't fail since the catch block is never executed. That's why we simply drag the test out of the catch block:

try {
$class->method('abc');
} catch(Exception $e) {
}
$this->assertIsA('Exception', $e);
unset($e);

Now the test fails when the exception isn't thrown because first of all $e won't be set and will surely not be an exception. It is important to add an unset($e), especially if you're testing for more exceptions directly afterwards.

Let's now assume that the method throws an InvalidArgumentException if the given parameter is not an integer.

try {
$class->method('abc');
} catch(Exception $e) {
}
$this->assertIsA('InvalidArgumentException', $e);
unset($e);

Now the test is in a state where it fails when no exception is thrown or when the thrown exception is not an InvalidArgumentException.

In case you're not lazy on typing, you might add one more line, which also allows you to put the assert back into the catch block:

try {
$class->method('abc');
$this->fail('Excepted exception was not thrown');
} catch(Exception $e) {
$this->assertIsA('InvalidArgumentException', $e);
unset($e);
}
		
		

5 comments

Dagfinn Reiersøls Gravatar

Dagfinn Reiersøl
21.04.2009, 12:53 o'clock

It's good to know this way of doing it, but the PHP test frameworks have features specifically for testing exceptions. SimpleTest (which seems to be the one in use here) has an expectException() method. (See http://forums.devnetwork.net/viewtopic.php?p=369062). PHPUnit has an @expectedException annotation.

Geoffrays Gravatar

Geoffray
22.04.2009, 13:30 o'clock

My comment will probably not change the world, but in your last example, shouldn't it be more logic if you also put the unset() back into the catch block ?

Regards

Dominik Jungowskis Gravatar

Dominik Jungowski
22.04.2009, 23:12 o'clock

You're absolutely right! I just changed it, thank you :)

templerels Gravatar

templerel
14.11.2009, 12:27 o'clock

Thank you for a very instructive article

kefAgifFkeXs Gravatar

kefAgifFkeX
07.12.2009, 03:24 o'clock

I don't know If I said it already but …Great site…keep up the good work. :) I read a lot of blogs on a daily basis and for the most part, people lack substance but, I just wanted to make a quick comment to say I'm glad I found your blog. Thanks, :)

A definite great read..

Write a comment

(will not be published)