Test-Mimic
view release on metacpan or search on metacpan
lib/Test/Mimic.pm view on Meta::CPAN
# Undo the @INC change
prepare_for_use();
return $success;
}
}
my $save_to; # The directory to read/write recorded behavior.
my $recording_required; # Will be set to true iff a package was requrested that has not yet been recorded.
# See the POD below.
sub import {
my ( $class, $user_preferences ) = @_;
if ( ! defined($user_preferences) ) {
die 'No preference hash reference passed to import in Test::Mimic.';
}
my %preferences = %{$user_preferences};
if ( ! defined( $preferences{'packages'} ) ) {
die 'No packages selected to mimic.';
}
$preferences{'test_mimic'} = ARBITRARY;
$save_to = $preferences{'save'} ||= '.test_mimic_data';
# Setup the library to behave per user preferences.
my $history = $save_to . '/history_for_playback.rec';
if ( -e $history ) { # This won't be true if we haven't recorded at all before.
load_records($history);
}
else {
init_records();
}
load_preferences(\%preferences);
# Attempt to load mimicked versions of each package. Note those that have not been recorded.
my $lib_dir = $save_to . '/lib';
my $playback_stage = 0;
my @to_record;
for my $package_to_mimic ( keys %{ $preferences{'packages'} } ) {
if ( ! require_from( $package_to_mimic, $lib_dir ) ) {
push( @to_record, $package_to_mimic );
}
else {
$playback_stage = 1;
}
}
# Prevent playback/recording conflicts.
if ( $playback_stage && @to_record > 0 ) {
die "The playback stage and the recording stage can not coincide. Either delete the current" .
"recordings or stop mimicking the following package(s): @to_record";
}
# Record the missing packages.
if ( @to_record != 0 ) {
$recording_required = 1;
require Test::Mimic::Recorder;
my %recorder_prefs = %preferences;
#Only include those packages that need recording.
$recorder_prefs{'packages'} = {};
for my $package (@to_record) {
$recorder_prefs{'packages'}->{$package} = $preferences{'packages'}->{$package};
}
Test::Mimic::Recorder->import(\%recorder_prefs);
}
}
# Handles the code generation after the recording is complete.
# NOTE: This relies on the LIFO structure of END block execution.
END {
if ($recording_required) {
my $generator = Test::Mimic::Generator->new();
$generator->load($save_to);
$generator->write($save_to);
}
}
1;
__END__
=head1 NAME
Test::Mimic - Perl module for automatic package and object mocking via recorded data.
=head1 SYNOPSIS
# Mimic the Foo::Bar package with defaults.
use Test::Mimic { 'packages' => { 'Foo::Bar' => {} } };
# Mimic the Foo::Bar package with alternatives.
use Test::Mimic {
'save' => '.test_mimic_data',
'string' => sub {}, # The sub {} construction simply represents a subroutine reference.
'destring' => sub {}, # See below for appropriate contracts.
'key' => sub {},
'monitor_args' => sub {},
'play_args' => sub {},
'packages' => {
'Foo::Bar' => {
'scalars' => [ qw< x y z > ],
'key' => sub {},
'monitor_args' => sub {},
'play_args' => sub {},
'subs' => {
'foo' => {
'key' => sub {},
'monitor_args' => sub {},
'play_args' => sub {},
},
},
},
},
};
=head1 DESCRIPTION
Test::Mimic allows one to easily mock a package by first recording its behavior and then playing it back.
All that is required is to use Test::Mimic prior to loading the real packages and then run the desired
program. The first run will be the recording phase and your program should behave normally. Subsequent runs
will use the recorded data to simulate the mimicked packages. This is the playback phase.
( run in 2.077 seconds using v1.01-cache-2.11-cpan-8f98c5d2c55 )