如何伪输入perl钻石运算符?

时间:2011-06-07 13:18:27

标签: perl unit-testing io diamond-operator

The answers to this question描述如何伪造<STDIN>的输入。我的目标与该问题类似:我的单元测试需要伪造<>的输入。

当我将相同的技术应用于伪造<>的输入时,它不起作用。对<>的介绍性解释让我相信,当命令行上没有给出文件时,它正在从STDIN读取,但似乎并非如此。

我正在尝试制作的样本:

#!/usr/bin/perl -w

use strict;
use warnings;
use Carp;
use English qw( -no_match_vars );

sub fake1 {
    my $fakeinput = "asdf\n";
    open my $stdin, '<', \$fakeinput
      or croak "Cannot open STDIN to read from string: $ERRNO";
    local *STDIN = $stdin;

    my $line = <>;
    print "fake1 line is $line\n";

    return 0;
}

sub fake2 {
    my $fakeinput = "asdf\n";
    open my $stdin, '<', \$fakeinput
      or croak "Cannot open STDIN to read from string: $ERRNO";
    local *STDIN = $stdin;

    my $line = <STDIN>;
    print "fake2 line is $line\n";

    return 0;
}

fake1();
fake2();

fake2有效,fake1没有。一个示例会话(“qwerty”是我打字):

$ perl /tmp/diamond.pl
qwerty
fake1 line is qwerty

fake2 line is asdf

我的问题:

  1. 如何伪造<>的输入?
  2. 在命令行上没有给出文件时,<><STDIN>之间有什么区别? (即,为什么链接问题中的技术适用于<STDIN>而不适用于<>?)
  3. 感谢。

1 个答案:

答案 0 :(得分:9)

在第一次测试中试试这个:

open ARGV, '<', \$fakeinput
      or croak "Cannot open STDIN to read from string: $ERRNO";

my $line = <>;
print "fake1 line is $line\n";

这样做的缺点是不是“本地的” - 不知道你是否可以在本地制作。 (你可以多次这样做,在每次测试之前重置。)