package MockModule;
use strict qw/subs vars/;
use Scalar::Util qw/reftype weaken/;
use Carp;
my %mocked;
sub new {
my $class = shift;
my ($package) = @_;
my $self = bless {
_package => $package,
_mocked => {},
}, $class;
$mocked{$package} = $self;
weaken $mocked{$package};
return $self;
}
sub mock {
my $self = shift;
while(my ($name, $value) = splice @_, 0, 2){
my $code = sub { };
if (ref $value && reftype $value eq 'CODE'){
$code = $value;
}
elsif (defined $value){
$code = sub {$value};
}
my $sub_name = _full_name($self, $name);
_replace_sub($sub_name, $code);
}
}
sub _full_name {
my ($self, $name) = @_;
sprintf "%s::%s",$self->{_package}, $name;
}
sub _replace_sub {
my ($sub_name, $code) = @_;
if(defined $code){
*{$sub_name} = $code;
}
}
1;
package MockTest;
use strict;
use warnings;
sub new {
my $class = shift;
my ($sub_name, $mock_info) = @_;
bless {
sub_name => $sub_name,_
mock_info => $mock_info
}, $class;
}
sub print_info {
my $self = shift;
print "$self->{sub_name} is $self->{mock_info} now!\n";
}
1;
#!/usr/bin/perl
use strict;
use warnings;
use MockModule;
use MockTest;
my $mock_before = MockTest->new('MockTest','unmock');
$mock_before->print_info();
my $mock = MockModule->new('MockTest');
$mock->mock(
'print_info',
sub {
print "Mock success!\n";
}
);
my $mock_after = MockTest->new('MockTest','unmock');
$mock_after->print_info();