vts
vts

Reputation: 911

how to test a subroutine which has 'exit' in it (perl)

For example:

dummy_mod.pl

package Dummy::Mod;

use warnings;
use strict;

sub print_and_exit {
    print "Hello World\n";
    exit;
}
1;

dummy_mod.t

use warnings;
use strict;

use Test::More;
use Test::Output;

plan tests => 2;
ok(require('dummy_mod.pl'), 'load test') or exit;
stdout_is(sub { Dummy::Mod->print_and_exit() }, "Hello World\n", "stdout test");

Then I got:

$ perl dummy_mod.t
1..2
ok 1 - load test
# Looks like you planned 2 tests but ran 1.

So seems the test script exit before test #2 finish. If I remove 'exit' from print_and_exit subroutine, it can work, but I don't want to do that in my real case. I've tried with:

stdout_is(sub { local $SIG{INT} = sub {}; Dummy::Mod->print_and_exit() }, "Hello World\n", "stdout test");

it doesn't work either.

Edit: The main purpose is testing the output from that subroutine, actually I don't care much about the exit code from it.

Upvotes: 2

Views: 668

Answers (1)

ThisSuitIsBlackNot
ThisSuitIsBlackNot

Reputation: 24073

You can use Test::Trap. Here's the example from the synopsis in the documentation:

use Test::More;
use Test::Trap;

my @r = trap { some_code(@some_parameters) };
is ( $trap->exit, 1, 'Expecting &some_code to exit with 1' );
is ( $trap->stdout, '', 'Expecting no STDOUT' );

Note that Test::Trap does more than just trap the exit; you can also use it to test STDOUT, STDERR, warnings, and more.

Upvotes: 3

Related Questions