I am testing a function that returns an array. The array could be different depending on the environment but it will always have at least one constant value (the one that I want to test).
As I am using Perl 5.12, I can use the smartmatch operator to find if the element is in the array:
ok($known_value ~~ @returned, 'testing method abc')
But I like the enhanced output of is
and like
with the "found" and "expected" parts. So I tried this:
cmp_ok($known_value, '~~', @returned, 'testing method abc')
This does not work because it seems that cmp_ok
expects a scalar in both parts of the comparison:
not ok 1 - testing method abc
# Failed test 'testing method abc'
# at abc.t line 53.
# 'stable_value'
# ~~
# '2'
The array in the "expected" slot is evaluated in scalar context and converted to 2.
I can work around this with a hack using like
and stringifying the array, but having a test where you can use the smartmatch operator as a comparison method (like when
) would be nice. Is there a way to do this with Test::More or some other module?
At the moment I am using:
ok($known_value ~~ @returned, 'testing method abc')
or diag (
"ERROR:\n".
"Found: ". Dumper @returned."\n".
"Expected at least one element equal to '$known_value'"
)
Is this the best that I can do?
You can't use @returned
because of how Perl passes arguments to subroutines. (Arrays are flattened into the argument list and lose their identity.) Pass an array reference instead:
cmp_ok($known_value, '~~', \@returned, 'testing method abc')
The smart match operator is smart enough to do the right thing. From perlsyn:
Note that the smart match implicitly dereferences any non-blessed hash or array ref, so the "Hash" and "Array" entries apply in those cases.