pytest-mockによる外部APIのモックについて あまりまだ使いこなせてないので、何か追加や間違ってることがある毎に修正予定。
pytest-mockのインストール
pip install pytest-mock
でok。
後で読む
まだmockで消耗してるの?mockを理解するための3つのポイント
request.getをモック
def test_views(client,mocker):
mocker.patch('request.get')
で最低限いける。テストメソッドの引数にmockerをつけると、mockerでMockを扱えるそうな。 戻り値に何か設定したい時は
res = mocker.Mock()
res.status_code = 200
mocker.patch('request.get').return_value = res
でよさげ
views内で使用したAPIをモック
from api import hogeapi
...
def index(request):
a = hogeapi(param)
result = a.hoge(param2)
みたいにviewsでapiがあって、そのコンストラクタをモックしたい時、
def test_views(client,mocker):
mocker.patch('api.hogeapi')
とやっても上手くいかず、APIを使ってしまう。調べてみるとこんな記事があった(pytest - Mocking constructor within constructorので試してみた。
これを読むとよさげ(Python の mock.patch のハマりやすい挙動についてまとめる)
def test_views(client,mocker):
mocker.patch('appname.views.hogeapi')
...
これでうまくいった。まだ原理が良くわかってない。
assert
上でモックしたapiのメソッドコールの回数を取得してassertするためには上のコードを修正してassertを追加する
def test_views(client,mocker):
m = mocker.patch('appname.views.hogeapi')
assert m.called_count == 1
assert m.return_value.hoge.called_count == 1
という感じにするインスタンスメソッドは一旦return_valueを経由してcall_countを取らないと表示されない