Testing Exceptions

     

Sometimes things go wrong. That's okay; sometimes the best thing to do in code that detects an unrecoverable error is to pitch a fit and let higher-level code figure out what to do. If you do that, though, you need to test that behavior. As usual, there's a module to make this easy. Test::Exception provides the functions to test that a block of code throws (or doesn't throw) the exceptions that you expect.

How do I do that?

Suppose that you're happy with add_positives( ) from "Testing Warnings," but your coworkers can't seem to use it correctly. They happily pass in negative numbers and ignore the warnings, and then blame you when their code fails to work properly. Your team lead has suggested that you strengthen the function to hate negative numbers ”so much so that it throws an exception if it encounters one. How can you test that?

Save the following listing as exception.t :

 use Test::More tests => 3;     use Test::Exception;     use Error;     sub add_positives     {         my ($l, $r) = @_;         throw Error::Simple("first argument ($l) was negative")  if $l < 0;         throw Error::Simple("second argument ($r) was negative") if $r < 0;         return $l + $r;     }     throws_ok { add_positives( -7,  6 ) } 'Error::Simple';     throws_ok { add_positives(  3, -9 ) } 'Error::Simple';     throws_ok { add_positives( -5, -1 ) } 'Error::Simple'; 


Note: There are no commas between the first and second arguments to any of Test:: Exception's test functions .

Run the file with prove :

 $  prove -v exception.t  exception....1..3     ok 1 - threw Error::Simple     ok 2 - threw Error::Simple     ok 3 - threw Error::Simple     ok     All tests successful.     Files=1, Tests=3,  0 wallclock secs ( 0.03 cusr +  0.00 csys =  0.03 CPU) 

What just happened ?

The call to throws_ok( ) ensures that add_positives( ) throws an exception of type Error::Simple . tHRows_ok( ) performs an isa( ) check on the exceptions it catches, so you can alternatively specify any superclass of the exception thrown. For example, because exceptions inherit from the Error class, you can replace all occurrences of Error::Simple in exception.t with Error .

What about...

Q:

How can you ensure that code doesn't throw any exceptions at all?

A:

Use Test::Exception 's lives_ok( ) function.

To ensure that add_positives( ) does not throw an exception when given natural numbers, add an extra test to assert that add_positives( ) throws no exceptions:

 use Test::More tests =>  4  ;     use Test::Exception;     use Error;     sub add_positives     {         my ($l, $r) = @_;         throw Error::Simple("first argument ($l) was negative")  if $l < 0;         throw Error::Simple("second argument ($r) was negative") if $r < 0;         return $l + $r;     }     throws_ok { add_positives( -7,  6 ) } 'Error::Simple';     throws_ok { add_positives(  3, -9 ) } 'Error::Simple';     throws_ok { add_positives( -5, -1 ) } 'Error::Simple';  lives_ok  { add_positives(  4,  6 ) } 'no exception here!';  

If the block throws an exception, lives_ok( ) will produce a failed test. Otherwise, the test will pass.



Perl Testing. A Developer's Notebook
Perl Testing: A Developers Notebook
ISBN: 0596100922
EAN: 2147483647
Year: 2003
Pages: 107

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net