How to Unit-Test for Expected Exception Thrown in Simpletest - *The* Answer

I keep forgetting how to assert that an Exception is going to be thrown in Simpletest version 1.0.1. So here is my notes for the record:

In summary:

== IF: ==

You want to have multiple Exception Expectations in a single SimpleTest Method,

== Then ==

You CANNOT use the expectException()  expectation in a single SimpleTest Method and expect a valid test

== Because ==

That particular test method will stop after the first Exception is thrown. Therefore, any following assertions within that test method will not be reached. But, other test methods that follow it WILL still be invoked.

* The test results may come out in a satisfyingly GREEN colour, BUT
* Assertions may have been skipped.

== IF ==

You want to have multiple Exception Expectations in a single SimpleTest Method

== Then ==

You CAN use something like this:

== Because ==

== If ==

The first Expected Exception Does NOT happen

(when the tested class is NOT working as it should)

== Then ==

* fail() logs the fail, and
Remember - There was NO exception, so
* The test method continues

== AND ==

== If ==

The first Expected Exception DOES happen

(when the tested class IS working as it should)

== Then ==

* the Exception IS caught, and
* pass() logs the pass, and
Remember - The exception was caught, so
* The test method continues
.
.
.
.

You don’t need to read any further than this  point

.
.
.
.
.
.
(But, I bet you are going to)
.
.

(BTW - I really should upgrade my wordpress blog - the text gets unformatted every time I submit the post )
.
.
(See - I guessed you’d read further…)

THE FOLLOWING TESTING LOGIC WORKS IN SIMPLETEST

*REALLY
* HONEST IT BLOODY DOES!
* I HAVE MADE SOME EXPECTATIONS FAIL AND MADE SOME PASS
* WHEN I MEAN FAIL I MEAN THAT THE TEST SUBJECT WAS NOT THROWING AN EXCEPTION WHEN IT WAS EXPECTED
* I HAVE MOVED THE FAILS ABOVE THE PASSES - AND IT STILL WORKS (the test counts are the same and I carefully looked at it with ‘’show passes” ON)

See the code example here

== Here’s why ==

———
The answer is ‘below the noise” on this page:
* www.sitepoint.com/forums/showthread.php?t=501505

With this answer on that page:

Quote 1:

It really boils down to this, you can either:
a) use the $this->expectException() and rely on SimpleTest default behavior which will not continue with code past where  the exception is thrown in your subject code
or b) write your own try() catch() blocks and exert greater control within the test method.

A little thought about this reveals why: Using the SimpleTest default behavior the try() block is wrapped around the call   to the test method itself, once your exception is thrown, there is no way to “return” to where you were before the exception was called.

Quote 2

(Answer:)

Apologies for bumping a very old thread but I found this thread when I was trying to figure out how to have SimpleTest  handle my exceptions and I discovered an error with the code listing above.

Just wanted to update this for posterity’s sake since this thread shows up on the first page of Google results for query  “simpletest catch exceptions”

….

The correct code should be:
<code>
try
{
$foo->methodThatGeneratesAnException();
$this->fail(”Exception was expected.”);
}
catch (Exception $e)
{
$this->pass();
}
</code>
Without adding that line, your tests that result in exceptions being generated won’t fail, but they won’t pass either giving you an incorrect count of passed tests.

——–

End of quotes

Credit to:
ghuytro and 33degrees and good ‘ol http://www.sitepoint.com/forums

and

of course

http://www.simpletest.org/

2 Responses to “How to Unit-Test for Expected Exception Thrown in Simpletest - *The* Answer”

  1. Ewald Says:

    To copy the full behaviour of expectException, you should define another catch:

    try{
    $something->generateSpecificException();
    $this->fail(’no exception was thrown’);
    } catch (SpecificException $e) {
    $this->pass();
    } catch (Exception $e) {
    $this->fail(’An exception was caught, but not of the expected type’);
    }

  2. John Says:

    Ewald. I generally avoid having too many types of Exception floating about as it can get messy.

    So, that was not in my mind when I wrote the piece. But, yes, if type is important, it makes total sense to add that extra catch. Thanks for the suggestion.

Leave a Reply