在不更改代码但添加测试的情况下很好
要测试的代码thefile.pl
get_name{
return 'sth';
}
测试test_thefile.t
use Test::More;
use Test::MockModule;
require thefile.pl
my $module = Test::MockModule->new('thefile.pl')
$module->mock(get_name => sub { return 'othername' });
my $name = get_name();
ok($name eq 'othername');
我得到
Invalid package name thefile.pl
最佳答案
您的问题是您将文件名用作裸词,因此 Perl 将其解释为包名称。由于 .
不是合法的标识符字符(可以在包名称中使用的字符),因此您会收到该警告。
如果您想使用文件名,请使用字符串:
require 'file.pl';
然后,在对 Test::MockModule
的调用中,它需要您在 file.pl 中定义的包的名称,而不是文件名。
我不知道你在做什么,但是当我想替换子例程定义时,我只需覆盖它即可。这是核心思想,暂时有办法做到。 Test::MockModule
和 Hook::LexWrap
等接口(interface)背后的代码并不复杂:
BEGIN {
require 'file.pl';
package Some::Package;
no warnings 'redefine';
*get_name = sub { ... }
}
glob (*get_name
) 有点棘手,但几乎所有其他内容都已经显示在您的示例中。我在 Effective Perl Programming 中展示了其中一些技巧。对于我的工作来说,减少模块依赖列表(尤其是在测试中)通常值得采用高级技巧。
关于unit-testing - 如何在 thefile.pl 中模拟函数而不是模块,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58084633/