For example in the following code how do I mock readline to unit test the do_stuff routine?
I think I require
I tried using FileHandle->new but got error - "readline() on unopened filehandle GEN1" which I took as readline() wasn't being mocked.
I tried an Test::MockObject (not extends), with readline() mocked, but that had the error "Not a GLOB reference" which reminded me that readline() isn't being called as a method.
package MyIO;
sub get_sock{ return IO::Socket::INET->new(@tcp_arg); }
sub do_stuff {
my $sock = get_sock();
my $line1 = <$sock>;
my $line2 = readline($sock);
return;
}
package TestMyIO;
sub test_do_stuff{
# my $mock_sock = Test::MockObject::Extends->new(IO::Socket::INET->new);
my $mock_sock = die("TODO");
my @fake_lines = ('line 1', 'line 2', 'line 3');
no warnings 'redefine'; ## no critic (ProhibitNoWarnings)
local *MyIO::get_sock = sub { return $mock_sock; };
local *MyIO::readline = sub { return shift @fake_lines; };
use warnings 'redefine';
}
You can use the following:
open(my $fh, '<', \$str);
This won't work if a system file handle is needed (eg if the handle needs to survive an exec
). But as long as you stick to Perl, reads from the handle will read from the provided buffer.
Builtins like readline
must be mocked in the CORE::GLOBAL
namespace, and must generally be defined at compile-time.
my @fake_lines;
BEGIN {
*CORE::GLOBAL::readline = sub { shift @fake_lines };
}
@fake_lines = ('line 1','line 2','line 3');
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.