我具有要测试的功能:
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/);
}
我在做什么错了?
答案 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;