6

I am writing some tests using Test::More, and one of the functions I'm testing prints to STDERR. I'd like to test the output to STDERR, but am a little unsure how to do this. I know I'm close. This works:

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

This prints out:

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

However, I don't want to close STDERR. I merely want to dup it.

I've tried this:

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

But, $error_string is blank.

What am I doing wrong?

4

3 回答 3

6

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

于 2013-08-21T04:00:39.583 回答
6

对我来说,open STDERR, ">&", $error_fh(连同open STDERR, ">&" . fileno($error_fh))不会返回真实值。我认为该>&模式可能是系统调用的一个非常直接的语法糖dup,它不适用于像$error_fh.

本地化怎么样STDERR

{
    local *STDERR = *$error_fh;
    say STDERR "something";
}
# STDERR restored
于 2013-08-20T18:58:33.840 回答
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.
"
于 2013-08-20T18:56:36.523 回答