The only help I've found on the internet so far is this blog. Which I thought was going to get me there, but I don't think it's actually changing the values in my module. I made a sample to show what I mean.
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;
And the test code:
#!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
If I use the Module::HOST
from the blog, I get a bareword compile error.
Is there some better way to mock a Readonly for a unit test?
The blog was probably written in the old days when Readonly was implemented in pure Perl using tie. Nowadays, Readonly is implemented using XS. To make a variable not readonly anymore, you can call
To be able to access the variable from outside of the module, it must be declared our, not my (as the blog correctly shows).
But the main question is: why do you need to test a different value in the variable, if the variable isn't supposed to be writable?