I am trying to Unit-Test my module Importer::Git that uses Git.pm from CPAN and I would like to mock the calls to Git::command,Git::repository and Git::command_oneline etc to not actually alter my filesystem. I tried to do this via Test::MockObject, but it seems I haven't fully understood the internal workings yet...
Example:
package Importer::Git
sub create_repository {
my ( $rc, $repo );
$rc = Git::command_oneline( 'init', $self->targetdir . "/" . $self->name );
$repo = Git->repository( Directory => $self->targetdir . "/" . $self->name );
$rc = $repo->command( 'config', 'user.name', $self->git_import_user->{ name } );
$self->_repo( $repo );
return $repo;
}
Testcase:
use Import::Git;
use Test::More tests => 1; # last test to print
use Test::Exception;
use Test::MockObject;
# pretend to have loaded the Git Module.
$INC{'Git.pm'} = 1;
my $git = Test::MockObject->new();
$git->fake_module('Git', repository => sub { $git } );
$git->set_true( qw(command command_oneline) );
$repo = Import::Git->init();
$repo->targetdir('./');
$repo->name('testrepo');
$repo->git_import_user({ name => 'test', email => 'test@test.com', push_default => 'testpush' });
$repo->create_repository();
But it does not seem to replace the git object in question as this test crashes with the messages from the actual Git.pm Module.
error: Malformed value for push.default: testpush
error: Must be one of nothing, matching, simple, upstream or current.
fatal: bad config variable 'push.default' in file '/home/.../testrepo/.git/config' at line 10
init .//testrepo: command returned error: 128
I guess in those two lines from Importer::Git it doesnt replace $repo
$repo = Git->repository( Directory => $self->targetdir . "/" . $self->name );
$rc = $repo->command( 'config', 'user.name', $self->git_import_user->{ name } );
So how would I mock that properly? I would like the $repo->command calls to just return 1.
UPDATE:
Daves guess was right. Correcting the code to this solved it:
use Test::More tests => 1; # last test to print
use Test::Exception;
use Test::MockObject;
my $git;
BEGIN {
# pretend to have loaded the Git Module.
$DB::single=1;
$INC{'Git.pm'} = 1;
$git = Test::MockObject->new();
$git->fake_module('Git', repository => sub { $git } );
$git->set_true( qw(command command_oneline) );
}
use Import::Git;
my $real_repo = Import::Git->init();
$real_repo->targetdir('./');
$real_repo->name('testrepo');
$real_repo->git_import_user({ name => 'test', email => 'test@test.com', push_default => 'testpush' });
$real_repo->create_repository();