2013-08-20 10 views
6

Sto scrivendo alcuni test utilizzando Test::More e una delle funzioni che sto testando stampa su STDERR. Mi piacerebbe testare l'output su STDERR, ma sono un po 'insicuro su come farlo. So di essere vicino. Questo funziona:Come posso testare STDERR con Test :: Altro?

use strict; 
use warnings; 
use feature qw(say); 

close STDERR; 
open STDERR, ">", \my $error_string; 

say STDERR "This is my message"; 
say qq(The \$error_string is equal to "$error_string"); 

Questo stampa:

The $error_string is equal to "This is my message 
" 

Tuttavia, non voglio chiudere STDERR. Voglio solo doppiarlo.

Ho provato questo:

use strict; 
use warnings; 
use feature qw(say); 

open my $error_fh, ">", my $error_string; 
open STDERR, ">&", $error_fh; 

say STDERR "This is my message"; 
close $error_fh; 
say qq(The \$error_string is equal to "$error_string"); 

Ma, $error_string è vuota.

Cosa sto sbagliando?

risposta

6

Per me, open STDERR, ">&", $error_fh (insieme a open STDERR, ">&" . fileno($error_fh)) non restituisce un valore vero. Penso che la modalità >& potrebbe essere uno zucchero sintattico piuttosto diretto per una chiamata di sistema dup, che non funzionerebbe su un pseudo-filehandle come $error_fh.

Che ne dici di localizzare STDERR?

{ 
    local *STDERR = *$error_fh; 
    say STDERR "something"; 
} 
# STDERR restored 
+0

Dang. Pensavo di aver usato "use autodie;" acceso. Quando lo aggiungo, ottengo "Impossibile aprire" GLOB (0x7fcb82829808) "con la modalità '> &': 'Bad file descriptor' in ./test.pl line 11'. Localizzare STDERR dovrebbe fare il trucco. –

2
# perl -MPerlIO::tee -MData::Printer -e 'my $output; STDERR->push_layer(tee=> \$output); warn "Danger, Will Robinson!"; p($output);' 
Danger, Will Robinson! at -e line 1. 
"Danger, Will Robinson! at -e line 1. 
"