Description
The semantics of expected exception testing could be better.
When you call setExpectedException()
is just overwrites an internal test-condition, which means you can't do more than one assertion within a single test.
What's worse though, if you have two statements after a call to setExpectedException()
, and you're expecting the first statement to trigger an exception, but it doesn't, and instead the second statement, which shouldn't, triggers the same type of exception - your test comes up green, but may actually be covering up two bugs.
What's missing, is some way to indicate precisely which statement is expected to generate the exception - for example:
/**
* Check for an expected exception, which must be thrown.
*
* @param mixed $exceptionName
* @param string $exceptionMessage
* @param int $exceptionCode
* @param callable $function
*
* @void
*/
public function assertException($exceptionName, $exceptionMessage, exceptionCode, $function)
{
try {
$function();
} catch (Exception $e) {
// ... check type/message/code and record assertion as passed/failed
return;
}
// ... mark assertion as failed (not thrown)
}
Using a closure, you can designate precisely which statement is expected to throw - and, you can test for any number of expected exceptions in the same test body.