为什么Test :: MockObject解冻我的对象会发出警告?

时间:2013-11-13 22:12:42

标签: perl unit-testing storable

这个需要一些解释才能开始。我有一个单元测试,我使用Class::Std::Fast::Storable保存SOAP::WSDL来自StorableMIME::Base64个对象。我存储的对象是webservice调用的结果。它最终用Test::MockObject编码并写入某个文件。这很有效。

当我构建单元测试时,我需要使用line 53 of anySimpleType.pm来模拟webservice的调用,从而返回已恢复的对象。但不知何故,这会引发一些关于在哈希元素中使用未初始化值的警告。

我尝试重新创建它作为一个小例子。第一段代码就是我如何获得示例的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

所以我看了{{3}},然后说:

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,它只会显示在正常的程序输出中。任何人都可以向我解释一下吗?

1 个答案:

答案 0 :(得分:0)

我仍然不知道为什么会发生这种情况。我的调试让我相信这些Storable对象总是抛出初始化警告。但是,如果Test :: MockObject不在那里,它们就会保持沉默。

所以让它关闭的解决方法如下:

local $SIG{__WARN__} = sub { warn $_[0] unless $_[0] =~ /uninitialized/};
local $/ = undef;
my $object = Storable::thaw(decode_base64(<DATA>));
ok( $object->get_value, 'foo' );