[Pdx-pm] Testing STDIN

Michael G Schwern schwern at pobox.com
Sat Aug 4 15:19:45 PDT 2007


Joshua Keroes wrote:
> I have a mock router class that prints to STDOUT and reads from STDIN.
> I'm a little unsure about how to test this.
> 
> The mock router is a state machine (implemented with Dave Wheeler's
> FSA::Rules). Each state typically prints a prompt, e.g.
> 
>     Username:
> 
> and waits for the user to type something, e.g.
> 
>     chomp( my $in = <STDIN> );
> 
> And of course, that <STDIN> will block while it waits for user-input.
> Seems like I need to fork the router process off into one process and
> connect it to another process that will pretend to be a fake user.
> 
> Is there a cleaner way to test this?

MakeMaker's test of prompt() shows how to tie STDIN.

http://search.cpan.org/src/MSCHWERN/ExtUtils-MakeMaker-6.36/t/prompt.t

SKIP: {
    skip "eof() doesn't honor ties in 5.5.3", 3 if $] < 5.006;

    $ENV{PERL_MM_USE_DEFAULT} = 0;
    close STDIN;
    my $stdin = tie *STDIN, 'TieIn' or die;
    $stdin->write("From STDIN");
    ok( !-t STDIN,      'STDIN not a tty' );

    is( prompt("Foo?", 'Bar!'), 'From STDIN',     'from STDIN' );
    like( $stdout->read,  qr/^Foo\? \[Bar!\]\s*$/,      '  question' );
}

1) close STDIN, though I don't remember why this was necessary
2) tie STDIN using TieIn
3) Put some stuff on STDIN using write()
4) Read from STDIN

You can steal TieIn for yourself.
http://search.cpan.org/src/MSCHWERN/ExtUtils-MakeMaker-6.36/t/lib/TieIn.pm


More information about the Pdx-pm-list mailing list