is_deeply测试忽略数组顺序?

时间:2012-03-01 20:01:35

标签: perl unit-testing

我正在寻找Test::More中的is_deeply测试例程。 来自Test::Deepcmp_bag但是这只能在数组本身上运行,而不是我传入的可靠的哈希数组哈希数据结构。是否有类似的东西:

is_deeply $got, $expected, {
    array => cmp_bag,
    # and other configuration...
}, "Ugly data structure should be the same, barring array order.";

澄清

我可以递归地钻研我的$expected$got对象并将数组转换为包对象:

sub bagIt {
    my $obj = shift;
    switch (ref($obj)) {
        case "ARRAY"    {
            return bag([
                map { $_ = bagIt($_) }
                @$obj
            ]);
        } case "HASH"   {
            return {
                map { $_ => bagIt( $obj->{$_} ) }
                keys %$obj
            };
        } else {
            return $obj;
        }
    }
}

我想知道是否有办法告诉is_deeply的某些变种为我这样做。

3 个答案:

答案 0 :(得分:2)

嗯,从Test::Deep docs开始,cmp_bag(\@got, \@bag, $name)只是cmp_deeply(\@got, bag(@bag), $name)的简写。

is_deeply( $got, {
    array => bag(qw/the values you expect/),
    # and other expected values
}, "Ugly data structure should be the same, barring array order." );

答案 1 :(得分:2)

使用您编写的bagIt函数,您始终可以为is_deeply创建一个适用于bagIt的包装器:

sub is_deep_bag {
   splice @_, 1, 1, bagIt($_[1]); 
   goto &is_deeply  # magic goto so that errors are reported on the right line
}

答案 2 :(得分:1)

看起来Test::Deep或其他Test::*个包中没有选项可将每个数组视为行李集。以下函数有效,但对于大数据结构的测试效率不高:

sub bagIt {
    my $obj = shift;
    my $ref = ref($obj);
    if ($ref eq 'ARRAY') {
        return Test::Deep::bag(
            map { $_ = bagIt($_) }
            @$obj
        );  
    } elsif ($ref eq 'HASH') {
        return {
            map { $_ => bagIt( $obj->{$_} ) } 
            keys %$obj
        };  
    } else {
        return $obj;
    }   
}

最后,我最终重构了我的代码,不依赖于这样的课程粒度测试。