你如何测试与间接对象语法一起使用的exec?

Sve*_*ess 3 perl unit-testing

测试使用间接对象语法调用exec的Perl脚本的最佳方法是什么?有没有办法模拟exec不会导致语法错误?我是否必须将exec移动到仅调用exec并模拟该函数的包装函数?或者有另一种方法来测试脚本吗?

第5章Perl的测试-开发人员的笔记本电脑有一个例子重写内置插件,他们覆盖system测试的模块.我想做同样的测试exec,但是在间接对象语法中.

exec.pl (使用间接对象语法)

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;
Run Code Online (Sandbox Code Playgroud)

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;
Run Code Online (Sandbox Code Playgroud)

prove -vt exec.t

这是不行的, exec不与间接对象语法,那里的工作内置的一样.

$ 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
Run Code Online (Sandbox Code Playgroud)

exec.pl (没有间接对象语法)

package Local::Exec;

use strict;
use warnings;

main() if !caller;

sub main {
    my $shell = '/usr/bin/ksh93';

    exec $shell;
    return;
}

1;
Run Code Online (Sandbox Code Playgroud)

prove -vt exec.t

仅供参考,这有效:

$ 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
Run Code Online (Sandbox Code Playgroud)

ike*_*ami 5

更换

exec { $shell } "-$shell0";
Run Code Online (Sandbox Code Playgroud)

sub _exec(&@) {
   my $prog_cb = shift;
   exec { $prog_cb->() } @_
}

_exec { $shell } "-$shell0"
Run Code Online (Sandbox Code Playgroud)

然后你的测试可以取代_exec.