2

到目前为止,我在互联网上找到的唯一帮助是这个博客。我认为这会让我到达那里,但我认为它实际上并没有改变我模块中的值。我做了一个样本来说明我的意思。

package Module;

use 5.012;
use strict;
use warnings;
use Readonly   qw( );

use parent     qw(Exporter);
our @EXPORT_OK = qw(
   &GetReadonly
);
our %EXPORT_TAGS = (
   all => [ @EXPORT_OK ] );

Readonly::Scalar my $HOST => 'host.web.server.com';

sub GetReadonly
{
   return $HOST;
}

1;

和测试代码:

#!perl

use strict;
use warnings;
use Test::More 'no_plan';
use Module qw/ :all /;

is($Module::HOST, 'host.web.server.com');     # HOST == undef

my $fake_host = 'fakemail.web.server.com';

{
   no warnings 'redefine';
   local *Readonly::Scalar::STORE = sub { ${$_[0]} = $_[1]; };
   $Module::HOST = $fake_host;
}

is(GetReadonly(), $fake_host);      # Returns host.web.server.com

如果我使用Module::HOST博客中的,我会得到一个裸字编译错误。

有没有更好的方法来模拟 Readonly 以进行单元测试?

4

1 回答 1

3

该博客可能是在过去使用tie在纯 Perl 中实现Readonly时编写的。如今,Readonly 是使用 XS 实现的。要使变量不再是只读的,您可以调用

Internals::SvREADONLY( $Module::HOST, 0 );

为了能够从模块外部访问变量,它必须声明为our,而不是my(正如博客正确显示的那样)。

但主要问题是:如果变量不应该是可写的,为什么需要在变量中测试不同的值?

于 2020-11-23T16:01:22.310 回答