I put together an example of an effective test:
The same name is used in the pass and fail so we know they match. It makes sure the exception branch is taken.my $test_name= "no such bundle"; try { HTML::EntityReference::ordinal('CapitalDifferentialD', ':fooXX'); fail ($test_name); } catch { my $exception= $_; like ($exception, qr/:fooXX/, "$test_name - mentions cause of erro +r"); like ($exception, qr/at t\/tests\.t/, "$test_name - carps correctl +y"); pass ($test_name); } ;
It also performs tests on the "die" string. I'd like to get the full file name and line number of the try'ed expression, but making sure the carp string gives this file is enough.
So if this were canned somehow, I need to specify the code to run, and sub-tests on the exception with suitable labels.
If there is nothing like this already, how have people been testing? How might I reuse this construct so I don't have to duplicate so much for every one I want to check?
Update:
With the suggestion of Test::Exception, my code becomes
Saving the contents of the exception string and then testing it after the catch block addressed one of my concerns, with test cases being on a conditional path, and how to get them inside the canned construct.my $test_name= "no such bundle"; dies_ok { HTML::EntityReference::ordinal('CapitalDifferentialD', ':foo +XX') } $test_name; like ($@, qr/:fooXX/, "$test_name - mentions cause of error"); like ($@, qr/at t\/tests\.t/, "$test_name - carps correctly");
But its use of $@ makes me worry that this doesn't handle modern (e.g. Moose) code, as with my own recent confusion as to $@ vanishing out from under me. It's fine for my immediate concern though.
Update again:
With the use of Test::Fatal, it becomes:
It's actually one more line, since exception doesn't itself report, and I have to save the exception in my own variable. That prevents problems with the ephemeral $@, but it is more noise. I wonder if my own implied global variable, or a localized $_, would be useful for something like that.my $test_name= "no such bundle"; my $err= exception { HTML::EntityReference::ordinal('CapitalDifferenti +alD', ':fooXX') } ; ok (defined $err, $test_name); like ($err, qr/:fooXX/, "$test_name - mentions cause of error"); like ($err, qr/at t\/tests\.t/, "$test_name - carps correctly");
I also found that the use of carp within the code still reports the call at test.t, not within the file that contains the exception function. Even though the docs implied that, I guess it is using some other technique to mark the function as "safe" to carp even though it is still on the call stack.
—John
In reply to testing the exception throwing by John M. Dlugosz
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |