Perl单元测试:检查字符串是否为数组

时间:2018-06-21 14:47:26

标签: arrays perl unit-testing

我具有要测试的功能:

use constant NEXT => 'next';
use constant BACK => 'back';

sub getStringIDs {
    return [
        NEXT,
        BACK
    ];
}

我尝试编写以下测试,但失败:

subtest 'check if it contains BACK' => sub {
    use constant BACK => 'back';
    my $strings = $magicObject->getStringIDs();
    ok($strings =~ /BACK/);
}

我在做什么错了?

3 个答案:

答案 0 :(得分:1)

$magicObject->getStringIDs的返回值是数组引用,而不是字符串。看起来,测试的精神是要检查数组模式中是否至少有一个元素与BACK相匹配。完成此操作的方法是通过解引用的数组grep并检查是否存在非零数量的匹配项。

ok( grep(/BACK/,@$strings) != 0, 'contains BACK' );

一次,smartmatch operator承诺将解决该问题……

ok( $strings ~~ /BACK/ )

但它有fallen into disrepute,应谨慎使用(和no warnings 'experimental::smartmatch'用法)。

答案 1 :(得分:1)

您的getStringIDs()方法返回一个数组引用。

正则表达式绑定运算符(=~)的左侧需要一个字符串。因此它将数组引用转换为字符串。字符串化数组引用看起来像ARRAY(0x1ff4a68)。它不会为您提供数组的任何内容。

您可以通过取消引用($strings)从数组引用(@$strings)到数组。而且,您可以通过将数组放在双引号("@$strings")中来对数组进行字符串化。

因此您可以执行以下操作:

ok("@$strings" =~ /BACK/);

但是我怀疑,您想要在其中添加单词边界标记:

ok("@$strings" =~ /\bBACK\b/);

您可能还希望使用like()测试功能。

like("@$strings", qr[\bBACK\b], 'Strings array contains BACK');

更新:另一种替代方法是使用grep来检查数组元素之一是否为字符串“ BACK”。

# Note: grep in scalar context returns the number of elements
# for which the block evaluated as 'true'. If we don't care how
# many elements are "BACK", we can just check that return value
# for truth with ok(). If we care that it's exactly 1, we should
# use is(..., 1) instead.

ok(grep { $_ eq 'BACK' } @$strings, 'Strings array contains BACK');

更新2:嗯...您在此处使用常量的事实使这一点变得复杂。常量是子例程,正则表达式是字符串,子例程不插值在字符串中。

答案 2 :(得分:1)

in operator是你的朋友。

use Test::More;
use syntax 'in';

use constant NEXT => 'next';
use constant BACK => 'back';

ok BACK |in| [NEXT, BACK], 'BACK is in the arrayref';
done_testing;