Существует ли способ переопределить Perl, “используют постоянный” в Вашем поблочном тестировании?

У меня есть модуль Perl, что я объявил некоторые константы:

use constant BASE_PATH => "/data/monitor/";

В живой операции никогда не будет изменяться константа, но я хочу смочь изменить ее в своих модульных тестах, например, установить ее на ~/project/testdata/. Существует ли путь, действительно делают это, не имея необходимость использовать глобальные изменяемые переменные?

Я мог возможно использовать Test::MockObject на constant?

5
задан Evan Carroll 18 November 2019 в 19:35
поделиться

4 ответа

При использовании констант они реализуются как функции констант. ведет себя примерно так:

use subs 'BASE_PATH';
sub BASE_PATH () {"/data/monitor/"}

Любое использование BASE_PATH в программе является встроенным и поэтому не может быть изменено.

Для достижения подобного вы можете вручную использовать прагму subs (чтобы заставить BASE_PATH вести себя как встроенную функцию) и объявить BASE_PATH как стандартная функция:

use subs 'BASE_PATH';
sub BASE_PATH {"/data/monitor/"}

print "BASE_PATH is ".BASE_PATH."\n";

*BASE_PATH = sub {"/new/path"};
print "BASE_PATH is ".BASE_PATH."\n";

Хотя я не совсем уверен, зачем вам это нужно.

6
ответ дан 18 December 2019 в 09:52
поделиться
package My::Class;

use constant BASE_PATH => "/a/real/value/";

# ..more code here..

1;

Теперь в ваших модульных тестах:

use My::Class;
*{My::Class::BASE_PATH} = sub { "/a/fake/value" };

# do your tests here...
2
ответ дан 18 December 2019 в 09:52
поделиться

Тесты часто выявляют негибкость дизайна. Это как-раз тот случай. Эта константа не должна быть постоянной.

Если вы делаете это из соображений производительности, я готов поспорить, что это не имеет никакого значения.

5
ответ дан 18 December 2019 в 09:52
поделиться

Очевидно, если ваше определение BASE_PATH было использовано / скомпилировано в другую подпрограмму ДО того, как ваш тест изменит его (через

*BASE_PATH = sub { ... }

или другой материал), у вас есть нет решения (потому что, когда исходный модуль использовал BASE_PATH как константу, он действительно определял функцию INLINE, которая была встроена при использовании в другом коде)

1
ответ дан 18 December 2019 в 09:52
поделиться
Другие вопросы по тегам:

Похожие вопросы: