Test::Mock::Guardを使ってみた

テストの時にこんな感じのことをして内部で使用しているメソッドの挙動を無理矢理変えていた。

{
    # てきとうなクラス
    package Hoge;
    sub hoge { 'hoge' }  # こいつを上書きしたい
}

say Hoge::hoge;  #=> hoge

sub run_with_mock {
    my %args = @_;

    no warnings 'redefine';
    *Hoge::hoge = $args{mock};

    $args{run}->();
}

run_with_mock(
    mock => sub {
        return 'homu';
    },
    run => sub {
        say Hoge::hoge;  #=> homu
    },
);

そしたら、レビューの時に先輩氏から「似たようなことがTest::Mock::Guardでできるから試してみると良いよ」的なことを言われたので試してみた。

say Hoge::hoge;  #=> hoge

{
    my $guard = mock_guard 'Hoge' => {
        hoge => sub { 'homu' },
        # hoge => 'homu',  値を返すだけならコードリファレンスにしなくても良い
    };

    say Hoge::hoge;  #=> homu
}

say Hoge::hoge;  #=> hoge

$guardが有効なスコープに限り、挙動を書き換えられる。 普段通りにテストを書くときは、わざわざ新たなスコープを作らなくてもsubtestを使うので、とくに深く考えなくても使えるから便利。

本筋の処理のネストが深くならずに済むのが地味にメリットだと思う。 ネストが深いと、それだけで読むのが辛くなってしまうからorz

以上、めもっす。