http://www.perlmonks.org?node_id=1039467

willjones has asked for the wisdom of the Perl Monks concerning the following question:

I have a structure I want to test for that comes back as a hash where one of the values is 'objects' which is an array of hash objects that have 2 fields that should always be present, but a 3rd field that may sometimes be present and sometimes not be present. When it is present I'd like to verify it with a re(...) comparison, but when it isn't present I'd like to prevent an error message telling me so... because it is optional! However if any other fields show up in there that aren't known optionals, I want to know about it. Does this make sense? How can I code this with Test::Deep? I read through the doc on cpan and noticed the superhash stuff, but I wasn't sure how to apply it with this array situation and also in such a way that met my specific needs. Any counsel would be appreciated... thanks.
my $myObjs = { alpha => re('^alpha(.*)'), beta => re('\d+'), #myOptionalField => re('^opt(.*)'), #sometimes there is a "myOpti +onalField", but sometimes there is not. What to do? }; cmp_deeply( $response, { field1 => re('\d+'), field2 => 2, field3 => 1, objects => array_each($myObjs) }, 'testing for valid response structure' );

Replies are listed 'Best First'.
Re: Unit testing question with Test::Deep
by pokki (Monk) on Jun 18, 2013 at 09:02 UTC

    Best I could come up with is this:

    use strict; use warnings; use 5.010; use Test::More; use Test::Deep; my $structure = [ { alpha => 'alpha-foo', beta => 18, gamma => 'opt-bar' }, { alpha => 'alpha-foo', beta => 18 } ]; my $structure_extra = [ { alpha => 'alpha-foo', beta => 18, gamma => 'opt-bar', delta => 'huh' }, { alpha => 'alpha-foo', beta => 18 } ]; my $structure_failing = [ { alpha => 'alpha-foo', beta => 18, gamma => 'copt-bar' }, { alpha => 'alpha-foo', beta => 18 } ]; my %minimal = ( alpha => re('^alpha(.*)'), beta => re('\d+') ); my %optional = ( gamma => re('^opt(.*)') ); my $validator = array_each(superhashof(\%minimal) & subhashof({%minima +l, %optional})); cmp_deeply($structure, $validator); cmp_deeply($structure_extra, $validator); cmp_deeply($structure_failing, $validator); done_testing;

    $structure passes the test, the other two fail. This can easily be modified to add new mandatory elements (add them to %minimal) and new optional elements (add them to %optional).

      Thanks, this is helpful.