views:

351

answers:

2

I am unit testing a component that requires user input. How do I tell Test::More to use some input that I predefined so that I don't need to enter it manually?

This is what I have now:

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;

This code does press enter but the function is retrieving 0 not 1;

+8  A: 

If the program reads from STDIN, then just set STDIN to be the open filehandle you want it to be:

#!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

You may want to read more about typeglobs in perldoc perldata and more about turning strings into fake files in the documentation for open (look for "Since v5.8.0, perl has built using PerlIO by default.") in perldoc perlfunc.

Chas. Owens
I just need to send in a 1\n in STDIN; This doesn't seem to work. *STDIN = "1\n";
kthakore
You must assign an open filehandle to the `*STDIN` typeglob. `"1\n"` is a string, not an open filehandle. Take a look at the second part of the example (the part that starts with `my $fakefile`) for a way of creating an open filehandle out of a string.
Chas. Owens
+4  A: 

The following minimal script seems to work:

#!/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');
}

Output:

C:\Temp> t
1..1
ok 1 - The object isa TestClass
Sinan Ünür