1. ホーム
  2. python

[解決済み] Python のモック patch.object を使って、他のメソッド内で呼び出されたメソッドの戻り値を変更する。

2022-05-18 12:16:18

質問

テストしようとしている他の関数内で呼び出された関数の戻り値をモック化することは可能でしょうか。モック化したメソッド(テスト中の多くのメソッドで呼び出されます)が呼び出されるたびに、指定した変数を返すようにしたいのです。例えば

class Foo:
    def method_1():
       results = uses_some_other_method()
    def method_n():
       results = uses_some_other_method()

ユニットテストでは、モックを使って uses_some_other_method() で呼び出されるたびに Foo で定義したものを返します。 @patch.object(...)

どのように解決するのですか?

パッチで解決する方法と、patch.objectで解決する方法の2つがあります。

パッチはオブジェクトを直接インポートしているのではなく、次のようにテストしているオブジェクトによって使用されていると仮定しています。

#foo.py
def some_fn():
    return 'some_fn'

class Foo(object):
    def method_1(self):
        return some_fn()

#bar.py
import foo
class Bar(object):
    def method_2(self):
        tmp = foo.Foo()
        return tmp.method_1()

#test_case_1.py
import bar
from mock import patch

@patch('foo.some_fn')
def test_bar(mock_some_fn):
    mock_some_fn.return_value = 'test-val-1'
    tmp = bar.Bar()
    assert tmp.method_2() == 'test-val-1'
    mock_some_fn.return_value = 'test-val-2'
    assert tmp.method_2() == 'test-val-2'

テストするモジュールを直接インポートする場合は、以下のようにpatch.objectを使用します。

#test_case_2.py
import foo
from mock import patch

@patch.object(foo, 'some_fn')
def test_foo(test_some_fn):
    test_some_fn.return_value = 'test-val-1'
    tmp = foo.Foo()
    assert tmp.method_1() == 'test-val-1'
    test_some_fn.return_value = 'test-val-2'
    assert tmp.method_1() == 'test-val-2'

どちらの場合も、テスト関数が完了した後、some_fnは「モックを解除」されます。

編集する 複数の関数をモックするには、関数にさらにデコレータを追加し、追加のパラメータを受け取るための引数を追加するだけです。

@patch.object(foo, 'some_fn')
@patch.object(foo, 'other_fn')
def test_foo(test_other_fn, test_some_fn):
    ...

デコレータが関数定義に近いほど、パラメータリストの中で早い位置にあることに注意してください。