How to use Test::Fatal for exception testing in Perl?
Question
How to use Test::Fatal for exception testing in Perl?
Test::Fatal is a handy Perl module designed to simplify testing code that throws exceptions (dies). It lets you easily capture exceptions during tests so you can assert whether an exception was thrown, and optionally inspect its message—all without needing complex eval blocks.
What is Test::Fatal?
Test::Fatal provides a function exception, which runs a code reference and captures any exception thrown. This helps write clean and readable tests focused on exception handling. Instead of manually wrapping code in eval blocks and checking $@, you just use exception to get the error string or undef if no exception occurred.
Basic Usage
To use Test::Fatal, you need Perl 5 installed (any modern version is fine). It is often used alongside Test::More or other testing modules.
Here’s what happens:
- You pass a
coderef(anonymous subroutine) toexception. - The coderef runs.
- If it
dies,exceptionreturns the string error. - If no exception, it returns
undef.
Common Perl Concepts:
coderef: an anonymous subroutine reference, e.g.sub { ... }$@: variable holding the last eval error (if any).die: function that throws exceptions in Perl.- TMTOWTDI ("There's more than one way to do it") allows exception testing via
eval,Try::Tiny, orTest::Fatal.
Example: Testing Exception with Test::Fatal
use strict;
use warnings;
use Test::More tests => 3;
use Test::Fatal;
# Function to test
sub divide {
my ($num, $den) = @_;
die "Division by zero error!" if $den == 0;
return $num / $den;
}
# Test 1: Normal division (no exception)
my $result = divide(10, 2);
is($result, 5, 'Divide 10 by 2 equals 5');
# Test 2: Check that division by zero throws exception
my $error = exception { divide(10, 0) };
like($error, qr/Division by zero error!/, 'Exception thrown for division by zero');
# Test 3: Check that no exception returns undef
my $no_error = exception { divide(5, 1) };
is($no_error, undef, 'No exception for valid division');
Explanation
1. We define a divide function which dies on division by zero.
2. The first test uses normal call and compares the result.
3. The second test uses exception to capture the die message from division by zero. We then confirm the error matches the expected regex.
4. The third test confirms no exception means exception returns undef.
Version Notes and Gotchas
Test::Fatalis core in Perl distributions from around 5.10, but availability might vary; you can install it from CPAN if needed.- Use
exceptiononly for code references; don't call the tested function directly because you wantexceptionto run and catch any exceptions. - Be careful of context (scalar vs list):
exceptionalways returns a scalar (the exception string orundef). - Combining
Test::Fatalwith other test modules likeTest::Moreallows more expressive tests.
In summary, Test::Fatal offers a clean and efficient way to write exception tests in Perl, saving you from manual eval handling and making tests simpler and more readable.
Verified Code
Executed in a sandbox to capture real output. • v5.34.1 • 69ms
1..3
ok 1 - Divide 10 by 2 equals 5
ok 2 - Exception thrown for division by zero
ok 3 - No exception for valid division
(empty)Was this helpful?
Related Questions
- How to use Test::Deep for complex data structure comparison?
- How to test Mojolicious applications in Perl?
- How to test HTTP responses with Test::WWW::Mechanize in Perl?
- How to use prove command to run Perl tests?
- How to test database code with Test::mysqld in Perl?
- How to test regular expressions with like in Perl Test::More?