Test::Resub - Lexically scoped subroutine replacement for testing
#!/usr/bin/perl use Test::More tests => 4; use Test::Resub qw(resub); { package Somewhere; sub show { my ($class, $message) = @_; return "$class, $message"; } } # sanity is( Somewhere->show('beyond the sea'), 'Somewhere, beyond the sea' ); # scoped replacement of subroutine with argument capturing { my $rs = resub 'Somewhere::show', sub { 'hi' }, capture => 1; is( Somewhere->show('over the rainbow'), 'hi' ); is_deeply( $rs->method_args, [['over the rainbow']] ); } # scope ends, resub goes away, original code returns is( Somewhere->show('waiting for me'), 'Somewhere, waiting for me' );
This module allows you to temporarily replace a subroutine/method with arbitrary code. Later, you can tell how many times was it called and with what arguments each time. You can also specify that the subroutine/method must get called, must not get called, or may be optionally called.
use Test::Resub qw(resub); my $rs = resub 'package::method', sub { ... }, %args;
is equivalent to:
use Test::Resub; my $rs = Test::Resub->new({ name => 'package::method', code => sub { ... }, %args, });
%args can be any of the following named arguments:
%args
The function/method which is to be replaced.
The code reference which will replace name. Defaults to sub {}
name
sub {}
Boolean which indicates whether or not arguments should be captured. A warning is emitted if you try to look at args without specifying a "true" capture. Defaults to 0.
capture
One of the following values (defaults to 'required'):
If the subroutine/method was never called when the Test::Resub object is destroyed, "not ok 1000" is printed to STDOUT.
If the subroutine/method was called when the Test::Resub object is destroyed, "not ok 1000" is printed to STDOUT.
It doesn't matter if the subroutine/method gets called. As a general rule, your tests should know whether or not a subroutine/method is going to get called, so avoid using this option if you can.
Boolean which indicates whether or not a function will be created if none exists. If the package can't resolve the method (i.e. ! UNIVERSAL::can($package, $method)), then an exception will be thrown unless 'create' is true. Defaults to false.
This is mainly useful to catch typos.
Whether or not to make a deep copy of saved-off arguments. Default is 1. Normally, one wants deep copies, but there is an associated performance penalty, e.g. for large objects.
Returns the number of times the replaced subroutine/method was called. The reset method clears this data.
reset
Returns the total number of times the replaced subroutine/method was called. This data is not cleared by the reset method.
Returns true if the replaced subroutine/method was never called. The reset method clears this data.
Clears the called, not_called, and args data.
called
not_called
args
Returns data on how the replaced subroutine/method was invoked. Examples:
Invocations: C<args> returns: ---------------------------- ------------------------- (none) [] foo('a'); [['a']] foo('a', 'b'); foo('d'); [['a', 'b'], ['d']]
Similar to args, but only returns unique argument calls. Given:
foo('a', 'b'); foo(1, 2); foo('a', 'b');
unique_args returns:
unique_args
[['a', 'b'], [1, 2]];
Objects of the same class are considered the same object.
Like args, but each invocation's arguments are returned in a hashref. Examples:
Invocations: C<named_args> returns: ---------------------------- ------------------------- (none) [] foo(a => 'b'); [{a => 'b'}] foo(a => 'b', c => 'd'); foo(e => 'f'); [{ a => 'b', c => 'd', }, { e => 'f', }]
The arg_start_index argument specifes that a certain number of arguments are to be discarded. For example:
arg_start_index
my $rs = resub 'some_sub'; ... some_sub('one', 'two', a => 1, b => 2); ... $rs->named_args(arg_start_index => 1); # returns ['two', {a => 1, b => 2}] $rs->named_args(arg_start_index => 2); # returns [{a => 1, b => 2}]
The scalars argument specifies that a certain number of scalar arguments precede the key/value arguments. For example:
scalars
my $rs = resub 'some_sub'; ... some_sub(3306, a => 'b', c => 123); some_sub(9158, a => 'z', c => 456); ... $rs->named_args(scalars => 1); # returns [3306, {a => 'b', c => 123}, # 9158, {a => 'z', c => 456}]
Note that named_args(scalars => N) will yield N scalars plus one hashref per call regardless of how many arguments were passed to the subroutine/method. For example:
named_args(scalars => N)
my $rs = Test::Resub->new({name => 'some_sub'}); ... some_sub('one argument only'); some_sub('many', 'arguments', a => 1, b => 2); ... $rs->named_args(scalars => 2); # returns ['one argument only', undef, {}, # 'many', 'arguments', {a => 1, b => 2}]
The named_args version of unique_args
named_args
Like args, but the first argument of each invocation is thrown away. This is used when you're resub'ing an object or class method and you're not interested in testing the object or class argument. Examples:
Invocations: C<method_args> returns: ---------------------------- ------------------------- (none) [] $obj->foo('a'); [['a']] Class->foo('a', 'b'); Class->foo('d'); [['a', 'b'], ['d']]
The method_args version of unique_args
method_args
Like named_args, but the first argument of each invocation is thrown away. This is used when you're resub'ing an object or class method and the arguments are name/value pairs. Examples:
Invocations: C<named_args> returns: ---------------------------- ------------------------- (none) [] $obj->foo(a => 'b'); [{a => 'b'}] $obj->foo(a => 'b', c => 'd'); [{ Class->foo(e => 'f'); a => 'b', c => 'd', }, { e => 'f', }]
named_method_args also takes a "scalars" named argument which specifies a number of scalar arguments preceding the name/value pairs of each invocation. It works just like named_args except that the first argument of each invocation is automatically discarded. For example:
named_method_args
my $rs = resub 'SomeClass::some_sub'; ... SomeClass->some_sub(3306, a => 'b', c => 123); SomeClass->some_sub(9158, a => 'z', c => 456); ... $rs->named_method_args(scalars => 1); # returns [3306, {a => 'b', c => 123}, # 9158, {a => 'z', c => 456}]
Note: the first argument is automatically discarded before the optional arg_start_index parameter is applied. That is,
my $rs = resub 'SomeClass::some_sub'; ... SomeClass->some_sub('first', b => 2); ... $rs->named_method_args(arg_start_index => 1); # returns [{b => 2}]
The named_method_args version of unique_args
Written at AirWave Wireless for internal testing, 2001-2007. Tidied up and released to CPAN in 2007.
The development team at AirWave Wireless, http://www.airwave.com/. Please direct questions, comments, bugs, patches, etc. to cpan@airwave.com.
To install Test::Resub, copy and paste the appropriate command in to your terminal.
cpanm
cpanm Test::Resub
CPAN shell
perl -MCPAN -e shell install Test::Resub
For more information on module installation, please visit the detailed CPAN module installation guide.