サイトアイコン たーちゃんの「ゼロよりはいくらかましな」

【python】【pytest-mock】呼び出し回数や引数で返却値を変える

昨日に引き続き、pythonネタで。

今日はmockしたメソッドが、呼び出し回数や、

与えられた引数によって返却したい値が異なっている場合にどうするか?

ということについてです。

 

 

 

常に同じ値を返却して良い場合

通常はあるmockのメソッドは1回しか呼ばれないか、

もしくは常に同じ値を返すだけでよい場合の方が多く、

以下のようになると思います。

def test_method() -> str:
    return hoge.get_data()

def test_get_data(self, mocker: MockFixture) -> None:
    mocker.patch('hoge.get_data').return_value = 'test'

    # hoge.get_dataの結果を返すテスト対象のメソッド
   ret: str = test_method()

    assert ret == 'test'

 

 

呼び出す回数で返却する値を変更したい場合

上記の例で例えば、hoge.get_dataが呼ばれるタイミングで違う値を返すような

メソッドであった場合、常に同じ値を返却してはテストになりません。

その場合は、以下のようにすることで実現できます。

def test_method() -> str:
    return hoge.get_data() + '-' + hoge.get_data()

def test_get_data(self, mocker: MockFixture) -> None:
    mocker.patch('hoge.get_data').side_effect = ['test1', 'test2']

    # hoge.get_dataの結果を返すテスト対象のメソッド
   ret: str = test_method()

    assert ret == 'test1-test2'

 

ポイントとしては、return_valueとしていたところを、

side_effectとすること、そして設定する値を配列で定義することです。

こうすることで、1回目の呼び出しではtest1、2回目の呼び出しではtest2と

返却されることになります。

 

 

呼び出された時の引数で返却する値を変更する

次に、例えばhoge.get_dataが引数を受け取る場合に、

渡された引数で値を変更したいというシーンもあると思います。

その場合は以下のようになります。

def get_data(param: str) -> str:
    # なんらかの処理
    return value

----------------------------------------------------------------------------------------

def test_method(param1:str, param2: str) -> str:
    return hoge.get_data(param1) + '-' + hoge.get_data(param2)

def test_get_data(self, mocker: MockFixture) -> None:

    def side_effect_method(param: str) -> str:
        if param == 'fuga':
            return 'test1'
        else:
            return 'test2'

    mocker.patch('hoge.get_data').side_effect = side_effect_method

    # hoge.get_dataの結果を返すテスト対象のメソッド
   ret: str = test_method('fuga', 'piyo')

    assert ret == 'test1-test2'

 

ポイントはside_effectで処理する内容を別メソッドとして、外に出して、

そのメソッドを設定することにあります。

もちろん無名関数でも大丈夫です。

ただ、引数はmockしたメソッドと同じにしてあげる必要があります。

 

 

まとめ

pytestのmockはわかりやすくてホントにいいですね。

今回の例でも直感的にわかりやすいものになっていて書きやすいなと

思いました。

Enjoy Mock!

 

それでは!!

 

 


にほんブログ村


人気ブログランキング

モバイルバージョンを終了