简体   繁体   English

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

[英]Why does Test::MockObject make thawing my objects throw warnings?

This one needs a bit of explanation to start with. 首先,需要一点解释。 I've got a unit test where I save Class::Std::Fast::Storable objects that come from SOAP::WSDL using Storable . 我有一个单元测试,其中使用Storable保存了来自SOAP :: WSDL的 Class :: Std :: Fast :: Storable对象。 The object I am storing is the result of a webservice call. 我存储的对象是Webservice调用的结果。 It ends up being encoded with MIME::Base64 and written somewhere to a file. 它最终以MIME :: Base64编码并写入文件的某个位置。 This is working great. 这很好。

When I was building up the unit test, I needed to use Test::MockObject to mock the call that webservice, thus returning the restored object. 在构建单元测试时,我需要使用Test :: MockObject来模拟对该Web服务的调用,从而返回已还原的对象。 But somehow this is throwing a bunch of warnings about the use of uninitialized value in hash element . 但这以某种方式引发了关于在散列元素中使用未初始化值的一系列警告。

I tried recreating it as a small example. 我尝试重新创建它作为一个小示例。 This first bit of code is how I get the base64 output for the example. 代码的第一部分是如何获取示例的base64输出的。 We will use it in a minute. 我们将在一分钟内使用它。

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));

So we got three lines of base64. 这样我们得到了三行base64。 Let's try to restore them: 让我们尝试还原它们:

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==

Neat. 整齐。 It works! 有用!

~> perl foo.t
1..1
ok 1 - foo

Now let's add Test::MockObject. 现在让我们添加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==

Ok, this is weird. 好的,这很奇怪。 It works, but it throws an error. 它可以工作,但是会引发错误。

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

So I looked at line 53 of anySimpleType.pm , and it says: 所以我看了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;

Hmm. 嗯。 $_[0] is undef. $_[0]未定义。 Looks like new was called without an argument. 看起来像new被称为没有参数。

But how the hell can loading Test::MockObject do that? 但是如何加载Test :: MockObject呢? Or maybe that warning is always popping up, but somehow it was not shown before? 或者,也许该警告总是弹出,但是以前没有显示过? I debugged it a little, and it turns out the warning is always showing in Komodo IDEs debugger, regardless of what I loaded. 我对其进行了一点调试,事实证明,无论我加载了什么内容,该警告始终在Komodo IDE调试器中显示。

However, it only shows up in the normal program output if I have Test::MockObject loaded as well. 但是,只有在我也加载了Test :: MockObject的情况下,它才会显示在常规程序输出中。 Can anyone explain that to me? 谁能向我解释?

I still don't know why this is happening exactly. 我仍然不知道为什么会这样。 My debugging led me to believe that the initialization warnings are always thrown by these Storable objects. 我的调试使我相信初始化警告总是由这些Storable对象引发的。 However, they are silent if Test::MockObject is not there. 但是,如果Test :: MockObject不存在,它们将保持沉默。

So the workaround to get it to shut up is as follows: 因此,关闭它的解决方法如下:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM