What's the best way to test my Perl script which calls exec with indirect object syntax? Is there a way to mock exec that doesn't lead to a syntax error? Do I have to move exec to a wrapper function that only calls exec and mock that function? Or is there another way to test the script?
Chapter 5 of Perl Testing - A Developer's Notebook has an example on Overriding Built-ins where they overwrite system
to test a module. I would like to do the same to test exec
, but in the indirect object syntax.
exec.pl
(with indirect object syntax) package Local::Exec;
use strict;
use warnings;
main() if !caller;
sub main {
my $shell = '/usr/bin/ksh93';
my $shell0 = 'ksh93';
# launch a login shell
exec {$shell} "-$shell0";
return;
}
1;
exec.t
#!perl
use strict;
use warnings;
use Test::More;
require_ok('./exec.pl');
package Local::Exec;
use subs 'exec';
package main;
my @exec_args;
*Local::Exec::exec = sub {
@exec_args = @_;
return 0;
};
is(Local::Exec::main(), undef, 'main() returns undef');
is_deeply(\@exec_args, [ '/usr/bin/ksh93' ], 'exec() was called with correct arguments');
done_testing;
prove -vt exec.t
This does not work, my exec
doesn't work with the indirect object syntax, where the built-in does.
$ prove -vt exec.t
exec.t .. String found where operator expected at ./exec.pl line 15, near "} "-$shell0""
(Missing operator before "-$shell0"?)
not ok 1 - require './exec.pl';
# Failed test 'require './exec.pl';'
# at exec.t line 8.
# Tried to require ''./exec.pl''.
# Error: syntax error at ./exec.pl line 15, near "} "-$shell0""
# Compilation failed in require at (eval 6) line 2.
Undefined subroutine &Local::Exec::main called at exec.t line 21.
# Tests were run but no plan was declared and done_testing() was not seen.
# Looks like your test exited with 255 just after 1.
Dubious, test returned 255 (wstat 65280, 0xff00)
Failed 1/1 subtests
Test Summary Report
-------------------
exec.t (Wstat: 65280 Tests: 1 Failed: 1)
Failed test: 1
Non-zero exit status: 255
Parse errors: No plan found in TAP output
Files=1, Tests=1, 1 wallclock secs ( 0.02 usr 0.01 sys + 0.04 cusr 0.01 csys = 0.08 CPU)
Result: FAIL
exec.pl
(without indirect object syntax) package Local::Exec;
use strict;
use warnings;
main() if !caller;
sub main {
my $shell = '/usr/bin/ksh93';
exec $shell;
return;
}
1;
prove -vt exec.t
Just for reference, this works:
$ prove -vt exec.t
exec.t ..
ok 1 - require './exec.pl';
ok 2 - main() returns undef
ok 3 - exec() was called with correct arguments
1..3
ok
All tests successful.
Files=1, Tests=3, 0 wallclock secs ( 0.02 usr 0.01 sys + 0.04 cusr 0.01 csys = 0.08 CPU)
Result: PASS
Replace
exec { $shell } "-$shell0";
with
sub _exec(&@) {
my $prog_cb = shift;
exec { $prog_cb->() } @_
}
_exec { $shell } "-$shell0"
Then your test can replace _exec
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.