Как мне изменить скаляр Perl только для чтения в модуле для модульного теста?

#unit-testing #perl #readonly #readonly-variable

#модульное тестирование #perl #только для чтения #переменная только для чтения

Вопрос:

Единственная помощь, которую я пока нашел в Интернете, — это этот блог. Я думал, что это приведет меня к этому, но я не думаю, что это на самом деле меняет значения в моем модуле. Я сделал образец, чтобы показать, что я имею в виду.

 package Module;

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

use parent     qw(Exporter);
our @EXPORT_OK = qw(
   amp;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 из блога, я получаю ошибку компиляции без слов.

Есть ли какой-нибудь лучший способ издеваться только для чтения для модульного теста?

Ответ №1:

Блог, вероятно, был написан в старые времена, когда Readonly был реализован в чистом Perl с использованием tie. В настоящее время функция Readonly реализована с использованием XS. Чтобы сделать переменную больше не доступной только для чтения, вы можете вызвать

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

Чтобы иметь возможность доступа к переменной извне модуля, она должна быть объявлена нашей, а не моей (как правильно показано в блоге).

Но главный вопрос заключается в следующем: зачем вам нужно проверять другое значение в переменной, если переменная не должна быть доступна для записи?

Комментарии:

1. Я занимаюсь модульным тестированием, поэтому мне нужен доступ к частным вещам. В этом случае я хочу изменить почтовый сервер и проверить условие ошибки. Обычно мы не хотим, чтобы эта информация была общедоступной, поэтому я бы предпочел не делать ее нашей переменной, если мне не нужно.

2. Если вам интересно, если я изменю переменную на our, ваше решение отлично работает. Если в любом случае есть возможность сохранить его в пределах модуля, я бы хотел это услышать.

3. @EricFossum В чем разница между предоставлением переменной напрямую через our или ее предоставлением через экспортируемую функцию GetReadOnly() ?

4. Эта функция была предназначена только для тестирования, если я ее установил. Ничто не возвращает это значение в моем продукте. код.

5. Какое условие ошибки вы пытаетесь проверить? Не лучше ли было бы имитировать соединение / запрос?