2011-09-21 50 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