Как я могу поймать вывод карпа в Perl?
Вопрос
Я пишу модуль Perl и использую carp, чтобы вернуть нефатальное предупреждение вызывающей программе.
Предупреждение о карпе работает нормально - я проверяю, соответствует ли входной параметр определенному условию - если он не соответствует условию, с помощью карпа отправляется предупреждение, и модуль продолжает использовать значение по умолчанию для параметра вместо того, которое вызывает программа. прошедший.Предупреждение предназначено только для уведомления о том, что вместо переданного параметра используется параметр по умолчанию.
Моя проблема связана с моим тестовым сценарием.Мой тестовый сценарий отправляет в модуль неправильный параметр, и я пытаюсь перехватить возвращаемое предупреждающее сообщение и убедиться, что получил правильное предупреждающее сообщение.
Мой модуль выглядит примерно так:
else {
carp "value must be numeric - using default value";
}
и мой тестовый скрипт выглядит так:
eval {
#call to my module
};
like (
$@,
qr/value must be numeric/,
"Should abort on non-numeric value"
);
Когда я запускаю тест, я вижу предупреждение (оно должно быть отправлено в STDERR) на экране, но содержимое переменной $@ равно '' - пусто.
Вот результат моего тестового сценария:
t/04bad_method_calls....ok 10/12value must be numeric - using default value at ...
# Failed test 'Should abort on non-numeric value'
# at t/04bad_method_calls.t line 98.
t/04bad_method_calls....NOK 12
# '' doesn't match '(?-xism:value must be numeric)'
# Looks like you failed 1 test of 12.
Если я меняю карпа на карпа, мой тестовый скрипт работает - ловит сообщение об ошибке (но я хочу только предупредить, а не прервать).
Честно говоря, я не очень хорошо понимаю eval — возможно, это не лучший способ поймать предупреждение от carp.Я попробовал использовать $SIG{ПРЕДУПРЕЖДАТЬ}, но это тоже было пусто.
Есть ли способ поймать добычу карпа?Это не так уж и важно, поскольку это касается только моего тестового сценария, но мне все равно хотелось бы, чтобы мой тестовый сценарий работал правильно.
Заранее спасибо!
Решение
С этой страницы http://perldoc.perl.org/perlvar.html, похоже, вы хотите установить локальный $SIG{__WARN__}
в подпрограмму, которая превратит предупреждения в фатальные ошибки для вашего тестового сценария.Пример, который они приводят:
local $SIG{__WARN__} = sub { die $_[0] };
eval $proggie;
Другие советы
Еще один способ, как ловить предупреждения, а также все STERR
выход:
my $stderr = '';
{
local *STDERR;
open STDERR, '>', \$stderr;
do_stuf_here();
}
like( $stderr, qr/my result/, 'test stderr output' );
Можно сделать причудливую тестовую функцию:
sub stderr_test (&$$) {
my ( $code, $pattern, $text ) = @_;
my $result = '';
{
local *STDERR;
open STDERR, '>', \$result;
$code->();
}
if ( UNIVERSAL::isa( $pattern, 'Regexp' ) ) {
like( $result, $pattern, $text );
}
else {
is( $result, $pattern, $text );
}
}
# usage
stderr_test {do_stuf_here} qr/my expected STDERR output/,
'stderr is like';
stderr_test {do_stuf_here} 'my expected STDERR output',
'stderr is exactly';
Если вы делаете это из тестового сценария, вы можете использовать модули Test::*, которые собирают выходные данные для вас.мне обычно нравится Тест::Вывод.