Как я могу поймать выход из карпа в Perl? - PullRequest
13 голосов
/ 27 января 2009

Я пишу модуль 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 - возможно, это не лучший способ поймать вывод предупреждения от карпа. Я пытался использовать $ SIG { WARN }, но это тоже было пусто.

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

Заранее спасибо!

Ответы [ 3 ]

19 голосов
/ 27 января 2009

На этой странице http://perldoc.perl.org/perlvar.html, похоже, что вы хотите установить для локальной $SIG{__WARN__} подпрограмму, которая превратит предупреждения в фатальные ошибки для вашего тестового сценария. Пример, который они приводят:

local $SIG{__WARN__} = sub { die $_[0] };
eval $proggie;
7 голосов
/ 27 января 2009

Другой способ, как перехватывать предупреждения, а также вывод 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';
6 голосов
/ 27 января 2009

Если вы делаете это из тестового скрипта, вы можете использовать модули Test :: *, которые собирают данные для вас. Мне нравится Test :: Output .

...