How can I unit test Perl functions that print to the screen?

后端 未结 3 525
广开言路
广开言路 2020-12-28 13:31

I\'m trying to use Test::More to unit test Perl functions that print to the screen.

I understand that this output may interfere with tools such as prove.

How

3条回答
  •  情深已故
    2020-12-28 13:53

    UPDATE: IMHO, the correct answer to this question ought to be to use Test::Output:

    #!/usr/bin/perl
    
    use strict; use warnings;
    
    use Test::More tests => 1;
    use Test::Output;
    
    sub myfunc { print "This is a test\n" }
    
    stdout_is(\&myfunc, "This is a test\n", 'myfunc() returns test output');
    

    Output:

    C:\Temp> tm
    1..1
    ok 1 - myfunc() returns test output
    

    I am leaving the original answer for reference as, I believe, it still illustrates a useful technique.

    You can localize STDOUT and reopen to a scalar before calling the function, restore afterward:

    #!/usr/bin/perl
    
    use strict; use warnings;
    
    use Test::More tests => 1;
    
    sub myfunc { print "This is a test\n" }
    
    sub invoke {
        my $sub = shift;
        my $stdout;
        {
            local *STDOUT;
            open STDOUT, '>', \$stdout
                or die "Cannot open STDOUT to a scalar: $!";
            $sub->(@_);
            close STDOUT
                or die "Cannot close redirected STDOUT: $!";
        }
        return $stdout;
    }
    
    chomp(my $ret =  invoke(\&myfunc));
    
    ok($ret eq "This is a test", "myfunc() prints test string" );
    diag("myfunc() printed '$ret'");
    

    Output:

    C:\Temp> tm
    1..1
    ok 1 - myfunc() prints test string
    # myfunc() printed 'This is a test'
    

    For versions of perl older than 5.8, you probably need to use IO::Scalar, but I do not know much about how things worked before 5.8.

提交回复
热议问题