我一直在阅读第二版中级Perl的第14章,其中讨论了测试Perl模块并使用Test :: More的功能.我是指本书在“添加我们的第一个测试”一节中直接发布的代码.
对于某些背景,在本章中,在一个具有相同名称的模块中创建了一个Animal类的示例.这个类有一个简单的讲法,如下所示:
sub speak { my $class = shift; print "a $class goes ",$class->sound,"!\n"; }
声音方法是为特定动物返回的简单字符串,因此,例如,马的声音方法将简单地称为“声音”,而且该方法应输出以下内容:
A Horse goes neigh!
我遇到的问题如下:在我在./Animal/t/Animal.t创建的测试代码中,我被指示使用裸块,Test :: More ::是测试说话方法正在工作.测试文件中的代码如下所示:
[test code snip] { package Foofle; use parent qw(Animal); sub sound { 'foof' } is( Foofle->speak,"A Foofle goes foof!\n","An Animal subclass does the right thing" ); }
测试失败.我运行了所有的Build命令,但是当运行“Build test”时,我会发现Animal测试失败:
Undefined subroutine &Foofle::is called at t/Animal.t line 28.
当我尝试显式地使用Test :: More :: is而不是简单的,测试仍然失败并显示以下消息:
# Failed test 'An Animal subclass does the right thing' # at t/Animal.t line 28. # got: '1' # expected: 'A Foofle goes foof! # '
我的方法似乎正如我所解释的那样定义.我认为第一个错误是一个范围问题,因为裸露的块,但不是100%确定.第二个错误我不确定,因为如果我要创建一个Foofle类作为一个Animal的孩子,并且在其上发言,我不会得到1的回应,而是预期的输出.
有人能够帮助我做错什么吗?对于可能的相关软件版本,我使用的是perl v5.16,Test :: More v0.98和Module :: Starter v1.58.
解决方法
看这个子程序:
sub speak { my $class = shift; print "a $class goes ","!\n"; }
…没有明确的return语句.在这种情况下,返回的是评估子程序的最新调用语句的结果,即评估打印内容的结果,即is 1(实际上是真的).
这就是为什么测试失败.您可以通过测试1修复它(但是这太简单了,我想)或者改变方法本身,这样它会返回一个打印的字符串.例如:
sub speak { my $class = shift; my $statement = "a $class goes " . $class->sound . "!\n"; print $statement; return $statement; }
…坦率地说,两种方法看起来都有点腥味.后一个虽然显然更完整,但实际上并不涵盖这种说法的所有功能:它会测试该声明是否正确,而不是是否打印. )