这需要一些解释才能开始。我有一个单元测试,我使用Storable保存来自SOAP::WSDL的Class::Std::Fast::Storable对象。我存储的对象是 web 服务调用的结果。它最终用MIME::Base64编码并写入文件的某个位置。这很好用。
在构建单元测试时,我需要使用Test::MockObject来模拟对 web 服务的调用,从而返回恢复的对象。但不知何故,这引发了一堆关于在 hash element 中使用未初始化值的警告。
我尝试重新创建它作为一个小例子。第一段代码是我如何获得示例的 base64 输出。我们将在一分钟内使用它。
use strict;
use warnings;
use MIME::Base64;
use Storable;
use SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType;
my $object = SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType->new;
$object->set_value('foo');
print encode_base64(Storable::freeze($object));
所以我们得到了三行base64。让我们尝试恢复它们:
use strict;
use warnings;
use MIME::Base64;
use Storable;
use Test::Simple tests => 1;
local $/ = undef;
my $object = Storable::thaw(decode_base64(<DATA>));
ok( $object->get_value, 'foo' );
__DATA__
BAgIMTIzNDU2NzgECAgIE0ADAQAAAAQDAQAAAAoDZm9vBQAAAHZhbHVlMAAAAFNPQVA6OldTREw6
OlhTRDo6VHlwZWxpYjo6QnVpbHRpbjo6YW55U2ltcGxlVHlwZYAwU09BUDo6V1NETDo6WFNEOjpU
eXBlbGliOjpCdWlsdGluOjphbnlTaW1wbGVUeXBlEAQICDEyMzQ1Njc4BAgICAUBAAAAAQ==
整洁的。有用!
~> perl foo.t
1..1
ok 1 - foo
现在让我们添加 Test::MockObject。
use strict;
use warnings;
use MIME::Base64;
use Storable;
use Test::Simple tests => 1;
use Test::MockObject; # <------- only line I changed
local $/ = undef;
my $object = Storable::thaw(decode_base64(<DATA>));
ok( $object->get_value, 'foo' );
__DATA__
BAgIMTIzNDU2NzgECAgIE0ADAQAAAAQDAQAAAAoDZm9vBQAAAHZhbHVlMAAAAFNPQVA6OldTREw6
OlhTRDo6VHlwZWxpYjo6QnVpbHRpbjo6YW55U2ltcGxlVHlwZYAwU09BUDo6V1NETDo6WFNEOjpU
eXBlbGliOjpCdWlsdGluOjphbnlTaW1wbGVUeXBlEAQICDEyMzQ1Njc4BAgICAUBAAAAAQ==
好吧,这很奇怪。它可以工作,但会引发错误。
1..1
Use of uninitialized value in hash element at /usr/lib/perl5/site_perl/5.16.2/SOAP/WSDL/XSD/Typelib/Builtin/anySimpleType.pm line 53, <DATA> chunk 1.
ok 1 - foo
所以我查看了 anySimpleType.pm 的第 53 行,它说:
my $OBJECT_CACHE_REF = Class::Std::Fast::OBJECT_CACHE_REF();
sub new {
my $self = pop @{ $OBJECT_CACHE_REF->{ $_[0] } }; # <-- here
$self = bless \(my $o = Class::Std::Fast::ID()), $_[0]
if not defined $self;
唔。$_[0]
是未定义的。看起来像是new
在没有参数的情况下被调用。
但是加载 Test::MockObject 到底是怎么做到的呢?或者也许这个警告总是弹出,但不知何故以前没有显示?我对其进行了一点调试,结果发现无论我加载了什么,Komodo IDE 调试器中总是显示警告。
但是,如果我也加载了 Test::MockObject,它只会显示在正常的程序输出中。谁能给我解释一下?