2013-04-09 28 views
0

因此試圖升級一些由其他人編寫的舊測試模塊來支持較新的perls。一些測試使用Test :: MockObject :: Extends,但是我發現運行下面的代碼錯誤。Test :: MockObject ::用'fields'擴展給出錯誤

#!/usr/bin/env perl 

package MyModule; 
use strict; 
use warnings; 
use fields qw(field1 field2); 

sub new { 
    my $self = shift; 
    unless (ref $self) { 
     $self = fields::new($self); 
    } 
    return $self; 
} 

package main; 
use strict; 
use warnings; 
use Test::MockObject::Extends; 
use Data::Dumper; 

my $VAR1 = MyModule->new(); 
print Data::Dumper::Dumper($VAR1); 
my $VAR2 = Test::MockObject::Extends->new($VAR1); 

錯誤:

$ perl a 
$VAR1 = bless({}, 'MyModule'); 
Modification of a read-only value attempted at /usr/local/share/perl/5.14.2/Test/MockObject/Extends.pm line 31. 

我已經看過了變更記錄,測試:: MockObject和Perl 5.10,不能看到任何直接看起來像它會導致此。我懷疑它已經被打破了一段時間,而5.10的新內容恰恰照亮了它。

回答

1

我想這裏發生的是使用fields :: new的結果。來自perldoc頁面:

 perl 5.9.0 and higher: fields::new() creates and blesses a 
     restricted-hash comprised of the fields declared using the "fields" 
     pragma into the specified class. 

我認爲Test :: MockObject :: Extends想修改散列,因此繁榮。

0

@ nfg的回答是正確的,但有一個簡單的解決方法:解鎖由fields創建的散列,然後傳遞給Test::Object::Extends

use Hash::Util qw(unlock_keys); 

my $obj = Some::Class->new(); 
unlock_keys(%$obj); 
$obj = Test::MockObject::Extends->new($obj); 

這將如果使用的是perl的< 5.9,因此,如果這是一個問題,那麼你可以有條件地解鎖按鍵失效。

在調用Test :: MockObject :: Extends並嘲笑任何要攔截的方法之後,您可能需要重新鎖定這些鍵,因爲否則,訪問不應存在於該對象中的字段的錯誤代碼將不會被捕獲。