Masteries

技術的なことや仕事に関することを書いていきます.

小ネタ: Test2でテストを書く時に, hashやarrayにundefがあることをU()でテストすると, なんか意図しない感じになることがある

またまたまたまた小ネタです. PerlのテストモジュールであるところのTest2において, U()undef であることをテストします.

is undef, U(); # => ok
is 1, U(); # => not ok

では, ハッシュや配列にundefがあることをテストしたい時はどうするといいでしょうか?

my $array = [ 'a', undef ];
is $array, array {
    item 'a';
    item U();
    end;
};

my $hash = { a => 1, b => undef };
is $hash, hash {
    field a => 1;
    field b => U();
    end;
};

一見良さそうに見えます(テストもパスします). が, 次の場合はどうでしょう.

my $array = [ 'a' ];
is $array, array {
    item 'a';
    item U();
    end;
};

my $hash = { a => 1 };
is $hash, hash {
    field a => 1;
    field b => U();
    end;
};

なんとこちらもパスします. undef があることをテストしたくてテストを書いたはずなので, このままだといけませんね.

この場合, きちんとundefが存在することをテストするには, U() ではなく, 明示的に undef を指定して, 比較する必要があります.

my $array = [ 'a' ];
is $array, array {
    item 'a';
    item undef; # エラー
    end;
};

my $hash = { a => 1 };
is $hash, hash {
    field a => 1;
    field b => undef; # エラー
    end;
};

このへんは, HASH BUILDERのところに,

# Ensure the key exists, but is set to undef
field bat => undef;

metacpan.org

...と書かれていました. なので, 「絶対にundefであることをテストしたい!」という場合は, 前述の通り U() を使わずに常に undef でテストしてあげましょう.