#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. Какое условие ошибки вы пытаетесь проверить? Не лучше ли было бы имитировать соединение / запрос?