インポートされたモジュールのコードを変更せずに、2 つのインポートが深い Python クラスをモックするにはどうすればよいですか? HTTPClient() をインポートする Web ユーティリティのライブラリをインポートするとします。ファイル web_utils.py を変更せずに、HTTPClient をモックして値を返す単体テストを作成するにはどうすればよいでしょうか? DataHandler でデータ操作を使用したい (モックアウトするのではなく)が、HTTPClient を実際に Web に接続したくありません。
これは可能ですか?Python にモンキー パッチがあることを考えると、そうあるべきだと思われます。または、代替/より良い方法はありますか? 私はまだモッキングプロセスを考え出しています.インポートを変更することはあまりありません.
# someLib/web_utils.py
from abc.client import SomeHTTPClient # the class to replace
def get_client():
tc = SomeHTTPClient(endpoint='url') # fails when I replace the class
return tc
class DataHandler(object):
def post_data(someURL, someData):
newData = massage(someData)
client = get_client()
some_response = client.request(someURL, 'POST', newData)
return some_response
# code/myCode.py
from someLib.web_utils import DataHandler
dh = DataHandler()
reply = dh.post_data(url, data)
# tests/myTests.py
from django.test.testcases import TestCase
from mock import Mock
class Mocking_Test(TestCase):
def test_mock(self):
from someLib import web_utils
fakeClient = Mock()
fakeClient.request = web_utils.SomeHTTPClient.request # just to see if it works
web_utils.SomeHTTPClient = fakeClient
dh = DataHandler()
reply = dh.post_data(url='somewhere', data='stuff')
更新 -get_client()
機能を追加しました。@spicavigoの答えは正しい軌道に乗っていると思います-SomeHTTPClient
クラスを置き換えているようです。しかし、何らかの理由で、クラスはオブジェクトをインスタンス化しません (エラーは、「型でなければならず、モックではありません」)。Mock()
クラスではなく、作成されたオブジェクトになる方法もわかりません。そのため、その部分を機能させる方法がわかりません。