概要
unittest の mock を使って request.get をモックする方法を紹介します
更に pytest の fixture を使います
環境
- macOS 11.7.10
- Python 3.11.6
- requests 2.32.3
- pytest 8.2.2
サンプルコード
httpbin にリクエストしてその結果を dict に変換します
- vim app.py
import requests
class HttpBinClient:
def __init__(self) -> None:
pass
def fetch(self) -> requests.Response:
return requests.get("https://httpbin.org/get")
def to_json(self, response: requests.Response) -> dict:
return response.json()
if __name__ == "__main__":
hbc = HttpBinClient()
res = hbc.fetch()
print(hbc.to_json(res))
テストコード
httpbin のレスポンスには url というフィールドがありアクセスした url が含まれているのでそれが正しいかテストするコードを作成します
- vim test/test_app.py
from app import HttpBinClient
class TestHttpBinClient:
def test_fetch(self):
hbc = HttpBinClient()
response = hbc.fetch()
result = hbc.to_json(response)
assert result["url"] == "https://httpbin.org/get"
- pipenv run pytest -s test/test_app.py
これで実行すると問題なく成功します
今回はこのテストにおいて requests.get で実際に外部にリクエストする部分をモックします
モックする conftest
conftest を使ってモックします
ポイントは requests.get に patch を当てつつ更にレスポンスのオブジェクトを正しく生成することです
- vim test/conftest.py
from unittest.mock import Mock, patch
import pytest
import requests
@pytest.fixture(autouse=True)
def mock_request_get():
with patch("requests.get") as m:
# requests のレスポンスオブジェクトを生成、理由は requests.get の返り値の型が requests.Response なため
response = requests.Response()
# json 関数をモックします、関数をモックする場合は Mock クラスを使って return_value でその関数の返り値を指定します
response.json = Mock(return_value={"url": "http://localhost"})
response.status_code = 200
# あとはモックオブジェクト (requests.get) の返り値に対してモックしたレスポンスを割り当てます
m.return_value = response
# 今回は with 句を使って patch しているため yield でモックオブジェクトを指定しなければいけません
yield m
動作確認
- pipenv run pytest -s test/test_app.py
で先程成功したテストが失敗することを確認します
モックでは実際にアクセスしないのでモックに指定した偽の返り値になるためエラーになります
最後に
pytest + unitest mock で requests.get をモックしていました
同じように post などもモックできます
0 件のコメント:
コメントを投稿