Pergunta

Estou escrevendo um módulo Perl e estou usando o CARP para lançar um aviso não fatal de volta ao programa de chamadas.

O aviso de carpa funciona bem - estou verificando se um parâmetro de entrada atender a uma certa condição - se não atender à condição, um aviso é enviado com o CARP e o módulo continua usando um padrão para o parâmetro em vez da que o programa de chamada passado. O aviso é apenas para notificar que um parâmetro padrão está sendo usado em vez do parâmetro passado.

Meu problema está no meu script de teste. Meu script de teste está enviando um parâmetro ruim para o módulo, e estou tentando pegar a mensagem de aviso que volta e garantir que eu recebi a mensagem de aviso correta.

Meu módulo se parece com o seguinte:

else {
  carp "value must be numeric - using default value";
}

E meu script de teste se parece com o seguinte:

eval {
  #call to my module
};
like (
    $@,
    qr/value must be numeric/,
    "Should abort on non-numeric value"
);

Quando executo o teste, posso ver o aviso (ele deve estar indo para o stderr) na tela, mas o conteúdo da variável $@ é '' - em branco.

Aqui está a saída do meu script de teste:

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.

Se eu mudar a carpa para um croak, meu script de teste funciona - ele captura a mensagem de erro (mas eu só quero avisar, não abortar).

Para ser sincero, não tenho o melhor entendimento da avaliação - talvez essa não seja a melhor maneira de obter a produção de aviso da Carp. Eu tentei usar $ sig {AVISAR}, mas isso também estava vazio.

Existe alguma maneira de capturar a saída da carpa? Não é o maior negócio, pois isso está apenas no meu script de teste, mas eu ainda gostaria de fazer com que meu script de teste funcione corretamente.

Desde já, obrigado!

Foi útil?

Solução

A partir desta página, http://perldoc.perl.org/perlvar.html, parece que você deseja definir o local $SIG{__WARN__} para uma sub -rotina que transformará avisos em erros fatais para o seu script de teste. O exemplo que eles dão é:

local $SIG{__WARN__} = sub { die $_[0] };
eval $proggie;

Outras dicas

Outra maneira de como pegar avisos e também todos STERR resultado:

my $stderr = '';
{
    local *STDERR;
    open STDERR, '>', \$stderr;
    do_stuf_here();
}
like( $stderr, qr/my result/, 'test stderr output' );

Pode -se fazer função de teste sofisticada:

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';

Se você estiver fazendo isso em um script de teste, poderá usar o teste ::* Módulos que capturam a saída para você. Eu tendem a gostar Teste :: saída.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top