package One; sub foo { return "foo\n"; } 1; package Count; use Scalar::Util qw/weaken/; sub new { return bless {}, shift; } sub unmock { my $self = shift; *One::foo = \&{ $self->{sub} }; } sub mock { my $thing = shift; my $self; if (ref($thing) eq __PACKAGE__){ $self = $thing; } else { $self = bless {}, __PACKAGE__; } weaken $self; $self->{sub} = \&One::foo; *One::foo = sub { $self->{x} = 'x'; return "baz\n"; }; return $self; } sub DESTROY { my $self = shift; print "destroying...\n"; $self->unmock; } 1;