最近使ったPerlのテスト系モジュール

最近Perlを書いていて,便利なテスト系モジュールをいくつか使ったのでメモ.

Test::Moreのsubtestメソッド

RSpecのitメソッドみたいな感じ.
テストをブロックに分けてそれぞれのブロックに名前を付けることができるイメージ.

use Test::More;

subtest "description" => sub {
    # テスト書く
}; 

Test::Mock::LWP::Conditional

LWP::UserAgentのリクエストスタブ.
LWP::UserAgentで任意のURLに対応するレスポンスを指定できる.

    my $res = HTTP::Response->new(200);
    $res->content("インターネット");
    Test::Mock::LWP::Conditional->stub_request("www.internet.com" => $res);
    
    # 以降,LWP::UserAgentで"www.internet.com"をGETしたらステータスコード200でcontentが"インターネット"で返ってくる

Test::MockObject::Extends

既存のクラスに含まれるメソッドをMockに置き換える.(Test::Mockは既存のクラスをMockに置き換える)

    # インスタンスメソッドをMockに置き換え
    my $internet = Net::Internet->new;
    my $mock = Test::MockObject::Extends->new($internet);
    $mock->set_always("service", +{ hatena => "www.hatena.ne.jp" });

    is $mock->service->{hatena}, "www.hatena.ne.jp";

    # newの引数にクラス名を指定することで,クラスメソッドを置き換えることもできる
    my $mock = Test::MockObject::Extends->new("Net::Internet");
    $mock->set_always("static_service", +{ twitter => "twitter.com" });

    is $mock->static_service->{hatena}, "twitter.com";

Test::Exception

croakやdieで投げた例外をテストできるモジュール.

    # doメソッドがcroak "No Such Internetを含むエラーメッセージ"を投げるかどうかテスト
    throws_ok {
        my $internet = Net::Internet->do("Facebook");
    } qr(No Such Internet);

Test::Mock::Guard

Mockオブジェクトを作成するモジュール.
Test::MockObjectよりもシンプル.

    # Net::InternetクラスをMock化する
    my $mock = mock_guard 'Net::Internet',
        +{
            do => sub { 
                my $self = shift;
                return +{ SAO => 'SwordArtOnline' };
             },
        };

    my $internet = Net::Internet->new;
    is $internet->do->{SAO}, 'SwordArtOnline';