13

この質問への回答は、への入力を偽造する方法を説明してい<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>ですか<>?)

ありがとう。

4

1 に答える 1

9

最初のテストでこれを試してください。

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

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

これには、「ローカル」ではないという欠点があります。ローカルにすることができるかどうかはわかりません。(ただし、各テストの前にリセットして、これを数回行うことができます。)

于 2011-06-07T13:36:18.157 に答える