在perl中进行单元测试时,我如何模拟GLOB ref的真实值?



例如,在下面的代码中,我如何模拟readline来对do_stuff例程进行单元测试?

我想我需要

  1. $sock必须是GLOB引用。
  2. readline()必须被模拟。

我尝试使用FileHandle->new,但得到错误"readline()在未打开的文件句柄GEN1"我认为readline()没有被嘲笑。

我尝试了Test::MockObject(不是extends), readline()模拟,但有错误"不是GLOB引用";这提醒了我,readline()不是作为方法调用的。

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';
}

您可以使用以下命令:

open(my $fh, '<', $str);

如果需要系统文件句柄(例如,如果句柄需要在exec中存活),这将不起作用。但是只要您坚持使用Perl,从句柄读取将从提供的缓冲区读取。

readline这样的内置必须在CORE::GLOBAL命名空间中模拟,并且通常必须在编译时定义。

my @fake_lines;
BEGIN {
*CORE::GLOBAL::readline = sub { shift @fake_lines };
}
@fake_lines = ('line 1','line 2','line 3');

最新更新