Reputation: 4617
I am trying to create unit tests for my script using the Test::More
and Test::Exception
libraries.
I have read these articles How to test for exceptions in Perl and Test::Exception.
The first article describes exactly what I need, to test my subroutine for throwing exception or dieing.
But I cannot get it working. Consider some examples
#!/usr/bin/env perl
package My::SuperModule;
use strict;
use warnings;
use Net::Ping;
use Utils::Variables::Validator;
sub new
{
die "Hello";
#Getting class name from, stored in $_[0]
my $class = shift;
#Getting user name from arguments $_[1]
my $user_name = shift;
........
}
And my test file
use warnings; # this warns you of bad practices
use strict; # this prevents silly errors
use Test::More; # for the is() and isnt() functions
use Test::Exception;
do './My/SuperModule.pm';
#Testing module loading
print "=================Testing module loading=================\n";
use_ok ( 'My::SuperModule' );
use_ok ( 'My::SuperModule', 'new' );
#Testing module subroutines
dies_ok { My::SuperModule->new() } "Died in class constructor";
sub div {
my ( $a, $b ) = @_;
return $a / $b;
};
dies_ok { div( 1, 0 ) } 'divide by zero detected';
It stops executing script in any case, but I need just to handle if died, I need to test this because I manually invoke die if data is invalid or something other , but it dies and doesn't continue to execute the script further. Giving me a message
Uncaught exception from user code:
Hello at ../libs/My/SuperModule.pm line 31.
My::SuperModule::new('My::SuperModule', '') called at SuperModule.t line 24
# Tests were run but no plan was declared and done_testing() was not seen.
# Looks like your test exited with 2 just after 8.
But if to use division by zero it works like I want
ok 16 - divide by zero detected
So it fails but doesn't terminate execution of the script.
I am newbie in Perl, so cannot solve the problem by myself, maybe there is not problem at all, just no way to do what I want.
Please suggest what to do or say where is my fault here.
EDIT
I have just tried to divide by zero inside my module new subroutine and here is the message I got.
Illegal division by zero at ../libs/My/SuperModule.pm line 33 (#1)
(F) You tried to divide a number by 0. Either something was wrong in
your logic, or you need to put a conditional in to guard against
meaningless input.
I really cannot figure out what is going on. Please help with this.
Upvotes: 3
Views: 1042
Reputation: 118128
Here is a minimal example that works:
package My::SuperModule;
use strict;
use warnings;
sub new {
die "Hello";
}
package main;
run() unless caller;
use Test::More;
use Test::Exception;
sub run {
dies_ok { My::SuperModule->new } "dies ok";
done_testing;
}
Output:
C:\...\t> prove -v my.pl my.pl .. ok 1 - dies ok 1..1 ok All tests successful. Files=1, Tests=1, 0 wallclock secs ( 0.09 usr + 0.00 sys = 0.09 CPU) Result: PASS
Note that, for the purpose of providing a self-contained example, I combined the module code and the test script into a single file.
Also note that I did not clutter the test script with unnecessary print
statements.
If you want, you can use diag
to show some output:
diag "Checking if Test::Exception::dies_ok will catch die in new";
dies_ok { My::SuperModule->new } "dies ok";
done_testing;
Output:
C:\...\t> prove my.pl my.pl .. # Checking if Test::Exception::dies_ok will catch die in new my.pl .. ok All tests successful. Files=1, Tests=1, 0 wallclock secs ( 0.05 usr + 0.02 sys = 0.06 CPU) Result: PASS
As opposed to plain print
statements, diag
output will actually be shown when tests are run from a harness such as prove
.
Upvotes: 4
Reputation: 69244
It works for me. All I needed to do was:
1;
as the last line of the module - so it returns a true value.require
and use_ok
from the test.done_testing;
to the end of the test - so the test harness knows that it got to the end of the tests.You probably don't care about the first item on that list, but if you fix the others, it should work for you.
Upvotes: 3