1

以下のシナリオでは、パラメーターmock exampleget_name()を持たないをモックする方法を知っていますが、引数として取る以下のシナリオをモックすることはできません。以下のモック関数を修正するのを手伝ってもらえますか?agetest_name

# data_source.py
def get_name(a):
    return "Alice"+str(a)

def get_age():
    return 30

Person クラスは、データ ソースからデータをフェッチするメソッドを公開します。

# person.py
from data_source import get_name

class Person(object):
    def name(self):
        age = get_age()
        return get_name(age)    

from mock import patch
from person import Person

@patch('person.get_name')
def test_name(mock_get_name):
    mock_get_name.return_value = "Bob"
    person = Person()
    name = person.name()
    assert name == "Bob"

前もって感謝します!

4

1 に答える 1

0

まず、 のインポートとは別に、 Person クラスで使用するため、get_nameもインポートする必要があります。get_age第二に、これまでにperson.get_name定義されたようなものはありません。したがって、パッチを適用することはできません。代わりに、おそらくパッチを適用したいと考えていましたdata_souce.get_name

しかし、残念ながら、それは機能しません。これdata_sourceは、Python モジュールであり、get_nameその中のメソッドを再定義する必要があるためです。たとえば、パッチ デコレータは、クラスget_name内のメソッドである場合に適しています。DataSourceモックライブラリの実装の詳細を深く掘り下げていないため、機能しない正確な理由はわかりませんが、ライブラリの意図は、使用方法とは異なります。

この問題を解決するには、data_source をクラスに変換するget_nameか、別の関数またはラムダを割り当てることでname の意味を一時的に変更することができます。

import data_source

def test_person():
    # replace the function
    data_source._real_get_name = data_source.get_name
    data_source.get_name=lamba a: "Bob"
    # do some work
    person = Person()
    name = person.name()
    # after use of the get_name function, put the original function back
    data_source.get_name=data_source._real_get_name
    # assert post condition
    assert name=="Bob"

もちろん、機能の変更はプログラムに深刻な影響を与えるため、注意して行う必要があります。おそらくテストのためだけです。エラーが予期せずスローされた場合でも、常に元の関数を元に戻すようにしてください。

于 2013-10-21T23:57:50.343 に答える