2011-09-21 66 views

回答

3

你可以抓住与canUNIVERSAL::can)未模拟的方法。之后,您可以使用goto它或者只使用&符号调用样式来传递相同的参数。这就是我在下面做的。

my $old_a = Package::To::Be::Mocked->can('a'); 
$pkg->mock(a => sub { 
     # do some stuff 
     &$old_a; 
}); 

当然,这是假设你的个子不AUTOLOAD或通过AUTOLOAD不需要重新定义can产生。 (我了解到几年前,如果你要惹AUTOLOAD,它可能是最好做的工作can

您还可以通过 入侵 修改Test::MockModule创建自己的工具,它会自动执行此,的名字空间。

{ package Test::MockModule; 
    sub modify { 
     my ($self, $name, $modfunc) = @_; 
     my $mock_class = $self->get_package(); 
     my $old_meth = $mock_class->can($name); 
     croak("Method $name not defined for $mock_class!") unless $old_meth; 
     return $self->mock($name => $modfunc->($old_meth)); 
    } 
} 

而且你可以把它像这样:

$mock->modify(a => sub { 
    my $old_a = shift; 
    return sub { 
     my ($self) = @_; 
     # my stuff and I can mess with $self 
     local $Carp::CarpLevel += 1; 
     my @returns = &$old_a; 
     # do stuff with returns 
     return @returns; 
    }; 
}); 
+0

如何嘲笑继承的载体作用? –

+0

@new_perl,如果你只是想覆盖在父类中定义的行为,mock应该为此工作。 'can'''''''''''''''''''''''''''交回一个对它分派的子引用 - 如果使用默认罐或程序员知道他或她在做什么。所以'modify' * should *也能工作,但是如果你只是想重写父函数,你也可以使用标准的'$ self-> SUPER :: a(@_);'(只要' $ self'已经从“deck”转移了。) – Axeman