如何使用Test :: More测试STDERR?

时间:2013-08-20 18:44:38

标签: perl file-io dup

我正在使用Test::More编写一些测试,我正在测试的其中一个函数打印到STDERR。我想测试输出到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是空白的。

我做错了什么?

3 个答案:

答案 0 :(得分:6)

对我来说,open STDERR, ">&", $error_fh(以及open STDERR, ">&" . fileno($error_fh))不会返回真值。我认为>&模式可能是dup系统调用的一个非常直接的语法糖,它不适用于像$error_fh这样的伪文件句柄。

如何本地化STDERR

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

答案 1 :(得分:6)

Test::Output可以做到,它现在使用Capture::Tiny来捕获边缘情况。

答案 2 :(得分: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.
"