Help us understand the problem. What is going on with this article?

PerlのTest Tips メソッド内で面倒な関数が呼ばれているから、回避したい場合

More than 5 years have passed since last update.

Perlのテストを作っているとき、あるメソッドで呼ばれている関数が邪魔なので、任意の値を返すようなモックにしたい場合。

邪魔な関数 = 例えば、その関数はネットワークアクスが必要とか、DBアクセスして、特定のデータセットが必要とか。

テスト対象モジュール
package TestTargetXXX;

use Some::Module qw(getIDfromDB);

sub sample_func {
    my $self = shift;
    my %param = @_;

    my $id = &getIDfromDB($param{key});
    # (略)
    return $key_code;
}
テストスクリプト(の一部)
subtest "sample_func test." => sub {
    my $obj = TestTargetXXX->new();

    %param = (key => 'XXX');
    $rtn = $obj->sampel_func(\%param);
    is $rtn, 'YYY';
};

ここで&getIDfromDB()を動かすには、DBの準備が必要で面倒。なので、モック化する。(もちろん、この関数は別途、テスト済み)

テストスクリプト(新)
subtest "sample_func test." => sub {
    my $test_id = undef;
    no warnings 'redefine';
    local *TestTarget::getIDfromDB = sub {return $test_id};
    use warnings 'redefine';

    my $obj = TestTargetXXX->new();

    %param = (key => 'XXX');
    $test_id = 'ZZZ';
    $rtn = $obj->sampel_func(\%param);
    is $rtn, 'YYY';
};

要点として、

  • *TestTarget::getIDfromDB = sub {...}で強制的に関数を置き換え
  • 置き換えが全体に影響しないようlocalで宣言
  • この置き換え方法は、警告が出るのでno wanings 'redefine';で抑制(use warnings;使ってないなら不要)

もう少し「強制的な置き換え」について説明すると、

  • getIDfromDB()は、TestTargetモジュール内でexportされている。
  • そのため、getIDfromDB()はSome::Moduleのものだが、TestTargetの関数ともいえる。
  • つまり、&TestTarget::getIDfromDB()ともいえる。
  • なので、*TestTarget::getIDfromDB = sub {}で強制的に上書き出来る。

最後に
CPANにありそうですが、Perl単体でなら上記の方法で対処可能。あと、モックの使いすぎ注意。別途、結合テストはきちんとする。そもそも、こんなテストしにくい実装はしない。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした