Avoid the vagueness of dies_ok() in Test::Exception
It's good to check that your code handles error conditions correctly, but dies_ok() in Test::Exception is too blunt an instrument to do it.
Consider this code that checks that the func() subroutine dies if not passed an argument.
#!/var/perl/bin/perl use warnings; use strict; use Test::More tests => 4; use Test::Exception; sub func { die 'Must pass arg' unless defined $_[0]; } # Test for failures if the arg is not passed. dies_ok( sub { func() }, '#1: Dies without an argument' ); throws_ok( sub { func() }, qr/Must pass arg/, '#2: Throws without an argument' ); lives_ok( sub { func(42) }, '#3: Lives with an argument' ); # Oops, we made a typo in our function name, but this dies_ok() still passes. dies_ok( sub { func_where_the_name_is_incorrect() }, '#4: Func dies without an argument' );
In case #4, the call to func_where_the_name_is_incorrect() indeed dies, but for the wrong reason. It dies because the function doesn't exist. If we had used throws_ok instead of dies_ok like so:
throws_ok( sub { func_where_the_name_is_incorrect() }, qr/Must pass arg/, '#4: Func dies without an argument' );
then the test would have failed because the exception was incorrect:
# Failed test '#4: Func dies without an argument' # at foo.t line 19. # expecting: Regexp ((?^:Must pass arg)) # found: Undefined subroutine &main::func_where_the_name_is_incorrect called at foo.t line 19.
Why do I post this? I found an example of this in some code I was working with, where the test had been passing for the wrong reason for the past six years. Take the time to be specific in what you check for.