I have this function that I want to test:
use constant NEXT => 'next';
use constant BACK => 'back';
sub getStringIDs {
return [
NEXT,
BACK
];
}
I've tried to write the following test, but it fails:
subtest 'check if it contains BACK' => sub {
use constant BACK => 'back';
my $strings = $magicObject->getStringIDs();
ok($strings =~ /BACK/);
}
What am I doing wrong?
The return value of $magicObject->getStringIDs
is an array reference, not a string. It looks like the spirit of your test is that you want to check if at least one element in the array pattern matches BACK
. The way to do this is to grep
through the dereferenced array and check if there are a non-zero number of matches.
ok( grep(/BACK/,@$strings) != 0, 'contains BACK' );
At one time, the smartmatch operator promised to be a solution to this problem ...
ok( $strings ~~ /BACK/ )
but it has fallen into disrepute and should be used with caution (and the no warnings 'experimental::smartmatch'
pragma).
Your getStringIDs()
method returns an array reference.
The regex binding operator ( =~
) expects a string on its left-hand side. So it converts your array reference to a string. And a stringified array reference will look something like ARRAY(0x1ff4a68)
. It doesn't give you any of the contents of the array.
You can get from your array reference ( $strings
) to an array by dereferencing it ( @$strings
). And you can stringify an array by putting it in double quotes ( "@$strings"
).
So you could do something like this:
ok("@$strings" =~ /BACK/);
But I suspect, you want word boundary markers in there:
ok("@$strings" =~ /\bBACK\b/);
And you might also prefer the like()
testing function.
like("@$strings", qr[\bBACK\b], 'Strings array contains BACK');
Update: Another alternative is to use grep
to check that one of your array elements is the string "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');
Update 2: Hmm... the fact that you're using constants here complicates this. Constants are subroutines and regexes are strings and subroutines aren't interpolated in strings.
The in
operator is your friend.
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;
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.