内部でAPI呼び出しを行う関数の単体テスト【Python】
pytest勉強中
以下のような、「内部でAPI呼び出ししている関数」の単体テストを 書くというケースに最近はじめて出会ったので、備忘メモを残します。
テスト対象コード
import requests def get_info(**kwargs): node = kwargs['auth'] app = node.get_information('sample') app_id = app.get_app_id() if app_id is None: raise requests.exceptions.HTTPError() url = 'https://sample.com/v1/app/' + str(app_id) headers = {'Authorization': 'Bearer ' + app.get_sample_key()} response = requests.get(url, headers=headers) try: response.raise_for_status() except requests.exceptions.RequestException as e: raise e data = response.json() return {'data': {'id': app.id, 'type': data} # 'type': 'sample-status'
テストコード
今回学びになったのは、mock.patchにside_effectという属性があり、 それとモック用の関数を使ってAPI呼び出しの振る舞いを再現できること。
読む人は少ないかもしれませんが、下のような感じでAPI呼び出しを モックしてテストできるようです。
def mocked_requests_get(*args, **kwargs): class MockResponse: def __init__(self, json_data, status_code): self.json_data = json_data self.status_code = status_code def raise_for_status(self): response = requests.Response() response.status_code = self.status_code try: response.raise_for_status() except requests.exceptions.HTTPError as e: raise e def json(self): return self.json_data if kwargs['headers']['Authorization'] == 'Bearer valid': return MockResponse('sample-status', 200) return MockResponse('null', 410) class TestGetInfo(unittest.TestCase) @mock.patch('requests.get', side_effect=mocked_requests_get) def test_get_info(self, mock_get): expected_res = {'data': {'id': app.id, 'type': 'sample-status'}} res = get_info(url=url, auth=app.auth) assert_equals(res.status_code, 200) assert_equals(res.json, expected_res) # 異常系は省略