Pregunta

Estoy escribiendo un módulo Perl y estoy usando carp para lanzar una advertencia no fatal al programa de llamadas.

La advertencia de carpa funciona bien: estoy comprobando si un parámetro de entrada cumple una determinada condición; si no cumple la condición, se envía una advertencia con carpa y el módulo continúa usando un valor predeterminado para el parámetro en lugar del el programa de llamada pasó. La advertencia es solo para notificar que se está utilizando un parámetro predeterminado en lugar del parámetro pasado.

Mi problema es con mi script de prueba. Mi script de prueba está enviando un parámetro incorrecto al módulo, y estoy tratando de captar el mensaje de advertencia que regresa y asegurarme de que recibí el mensaje de advertencia correcto.

Mi módulo se parece a esto:

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

y mi script de prueba se ve así:

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

Cuando ejecuto la prueba, puedo ver la advertencia (debe ir a STDERR) en la pantalla, pero el contenido de la variable $ @ está '' - en blanco.

Aquí está el resultado de mi script de prueba:

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.

Si cambio la carpa a croata, mi script de prueba funciona: detecta el mensaje de error (pero solo quiero advertir, no abortar).

Para ser honesto, no tengo la mejor comprensión de eval, tal vez esa no sea la mejor manera de captar la salida de advertencia de la carpa. Intenté usar $ SIG { WARN }, pero eso también estaba vacío.

¿Hay alguna forma de capturar la salida de la carpa? No es el mejor negocio ya que esto solo está en mi script de prueba, pero todavía me gustaría que mi script de prueba funcione correctamente.

¡Gracias de antemano!

¿Fue útil?

Solución

Desde esta página, http://perldoc.perl.org/perlvar.html , parece que desea establecer el $SIG{__WARN__} local en una subrutina que convertirá las advertencias en errores fatales para su script de prueba. El ejemplo que dan es:

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

Otros consejos

Otra forma de captar advertencias y también todos los STERR resultados:

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

Se puede hacer una función de prueba elegante:

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

Si está haciendo esto desde un script de prueba, puede usar los módulos Test :: * que capturan la salida por usted. Me suele gustar Test :: Output .

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top