2013-08-20 10 views
6

私はTest::Moreを使っていくつかのテストを書いており、テストしている機能の1つがSTDERRに印刷されています。私はSTDERRへの出力をテストしたいと思いますが、これを行う方法は少し不明です。私は私が近くにいることを知っている。これは動作します:Test :: MoreでSTDERRをテストするにはどうしたらいいですか?

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"); 

これはアウト出力します

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

をしかし、私はSTDERRを閉じるにはしたくありません。私は単にそれを捨てたい。

私はこれを試してみた:

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"); 

しかし、$error_stringは空白です。

私は間違っていますか? (open STDERR, ">&" . fileno($error_fh)と一緒に)私にとっては

答えて

6

open STDERR, ">&", $error_fhは真の値を返しません。私は>&モードがdupシステムコールのためのかなり直接構文的な砂糖かもしれないと思う。それは$error_fhのような擬似ファイルハンドルでは動作しないだろう。

STDERRをローカライズするのはどうですか?

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

Dang。私は 'autodieを使う 'と思った。私がそれを追加すると、GLOB(0x7fcb82829808) 'with mode'>& ':' Bad file descriptor 'が./test.pl 11行目にあります。 STDERRをローカライズすることはそのトリックを行うべきです。 –

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. 
" 
6

Test::Outputはそれを行うことができ、それが今でエッジケースをキャッチするCapture::Tinyを使用しています。

関連する問題