使用Test :: More测试Perl模块(中级Perl,第14章)

rsa*_*rsa 10 testing perl module

这是Stack Overflow的第一个问题.如果我打破一些规则,请提前道歉.

我一直在阅读Intermediate Perl的第14章,第2版,其中讨论了测试Perl模块和使用Test :: More的功能.我指的是在本书的"添加我们的第一次测试"一节中直接发布的代码.

对于某些背景,在本章中,将Animal在具有相同名称的模块中创建示例类.这个类有一个简单的speak方法,如下所示:

sub speak {
    my $class = shift;
    print "a $class goes ", $class->sound, "!\n";
}
Run Code Online (Sandbox Code Playgroud)

sound方法是为特定Animal返回的简单字符串,因此,例如,Horse的sound方法将是简单的sub sound { "neigh" },它的speak方法应输出以下内容:

A Horse goes neigh!
Run Code Online (Sandbox Code Playgroud)

我遇到的问题如下:在我在./Animal/t/Animal.t创建的测试代码中,我被指示使用裸块并Test::More::is测试该speak方法是否正常工作.代码在测试文件中如下所示:

[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"
    );
}
Run Code Online (Sandbox Code Playgroud)

测试失败.我运行了所有Build命令,但是在运行"Build test"时,我对Animal测试失败了:

Undefined subroutine &Foofle::is called at t/Animal.t line 28.
Run Code Online (Sandbox Code Playgroud)

当我尝试显式使用Test::More::is而不仅仅是普通时is,测试仍然失败并显示以下消息:

#   Failed test 'An Animal subclass does the right thing'
#   at t/Animal.t line 28.
#          got: '1'
#     expected: 'A Foofle goes foof!
# '
Run Code Online (Sandbox Code Playgroud)

我的方法似乎与我解释的完全一致.我认为第一个错误是范围问题,因为裸块,但不是100%肯定.第二个错误我不确定,因为如果我要创建一个Foofle类作为孩子Animal并且调用speak它,我不会得到1响应,而是预期的输出.

有人能够帮助解决我可能做错的事吗?对于可能相关的软件版本,我使用的是perl v5.16,Test :: More v0.98和Module :: Starter v1.58.

rai*_*7ow 5

您已正确解释了第一个错误的原因,并将其修正(指定了正确的包名称).但是你似乎错过了一个简单的事实:speakAnimal类的方法不是return这个a $class goes...字符串 - 它返回打印它的结果(这是1)!

看,这个子程序:

sub speak {
    my $class = shift;
    print "a $class goes ", $class->sound, "!\n";
}
Run Code Online (Sandbox Code Playgroud)

......没有明确的return陈述.在这种情况下返回是评估子程序调用的最新语句的结果-即评估结果print something,这 1(true实际上).

这就是测试失败的原因.您可以通过测试来修复它1(但我认为这太微不足道了)或者更改方法本身,因此它将返回它打印的字符串.例如:

sub speak {
    my $class = shift;
    my $statement = "a $class goes " . $class->sound . "!\n";
    print $statement;
    return $statement;
}
Run Code Online (Sandbox Code Playgroud)

......坦率地说,这两种方法看起来有点......可疑.后者虽然显然更完整,但实际上并不涵盖此speak方法的所有功能:它测试语句是否正确,但不测试是否打印.)