如何在Perl中伪造STDIN?

kth*_*ore 22 perl unit-testing

我正在测试需要用户输入的组件.如何告诉我Test::More使用我预定义的输入,以便我不需要手动输入?

这就是我现在拥有的:

use strict;
use warnings;
use Test::More;
use TestClass;

    *STDIN = "1\n";
    foreach my $file (@files)
    {

#this constructor asks for user input if it cannot find the file (1 is ignore);
    my $test = TestClass->new( file=> @files );

    isa_ok( $test, 'TestClass');
    }


done_testing;
Run Code Online (Sandbox Code Playgroud)

这段代码确实按回车,但函数检索0而不是1;

Cha*_*ens 17

如果程序从中读取STDIN,则只需设置STDIN为您希望它的打开文件句柄:

#!perl

use strict;
use warnings;

use Test::More;

*STDIN = *DATA;

my @a = <STDIN>;

is_deeply \@a, ["foo\n", "bar\n", "baz\n"], "can read from the DATA section";

my $fakefile = "1\n2\n3\n";

open my $fh, "<", \$fakefile
    or die "could not open fake file: $!";

*STDIN = $fh;

my @b = <STDIN>;

is_deeply \@b, ["1\n", "2\n", "3\n"], "can read from a fake file";

done_testing; 

__DATA__;
foo
bar
baz
Run Code Online (Sandbox Code Playgroud)

您可能希望阅读有关typeglobsperldoc perldata更多信息以及更多关于将字符串转换为伪文件的文档open(查找"自v5.8.0开始,perl默认使用PerlIO构建.")in perldoc perlfunc.

  • 您必须为`*STDIN` typeglob分配一个打开的文件句柄.`"1 \n"`是一个字符串,而不是一个打开的文件句柄.看一下示例的第二部分(以`my $ fakefile`开头的部分),了解如何从字符串中创建一个打开的文件句柄. (3认同)

Sin*_*nür 7

以下最小脚本似乎有效:

#!/usr/bin/perl

package TestClass;
use strict;
use warnings;

sub new {
    my $class = shift;
    return unless <STDIN> eq "1\n";
    bless {} => $class;
}

package main;

use strict;
use warnings;

use Test::More tests => 1;

{
    open my $stdin, '<', \ "1\n"
        or die "Cannot open STDIN to read from string: $!";
    local *STDIN = $stdin;
    my $test = TestClass->new;
    isa_ok( $test, 'TestClass');
}
Run Code Online (Sandbox Code Playgroud)

输出:

C:\Temp> t
1..1
ok 1 - The object isa TestClass