我尝试使用
side_effect
属性通过模拟上的每次调用来获取不同的响应。然而,我每次都会获得第一个。我想问一下我是否可以得到任何帮助。先谢谢你了
import json
from typing import Dict
from unittest.mock import Mock, patch
import requests
def mock_response_1() -> dict:
return {"data": {"users": [{"id": "AAA"}]}}
def mock_response_2() -> dict:
return {"data": {"users": [{"id": "BBB"}]}}
def mock_json_response(mocked_json: Dict, status_code: int = 200) -> Mock:
response_mock = Mock()
response_mock.configure_mock(**{
"return_value.status_code": status_code,
"return_value.headers": {"Content-Type": "application/json"},
"return_value.json.return_value": mocked_json,
"return_value.text.return_value": json.dumps(mocked_json),
})
return response_mock()
class ApiClient:
def get_response(self) -> dict:
request_r = requests.get(url="https://api.test.com")
request_r = request_r.json()
return request_r.get("data")
class MockClient(ApiClient):
@patch('ApiTest.requests.get')
def get_response(self, mocked_post: Mock):
mocked_post.side_effect = iter([
mock_json_response(mock_response_1()),
mock_json_response(mock_response_2())
])
return super().get_response()
class TestApiClient:
client = MockClient()
def test_get_response(self):
for i in (0, 1):
print(f"Iteration {i}: {self.client.get_response()}")
结果:
Iteration 0: {'users': [{'id': 'AAA'}]}
Iteration 1: {'users': [{'id': 'AAA'}]}
您的代码副作用迭代器在每次调用 get_response() 时都会重置,导致两次迭代返回相同的响应。
另外,MockClient 的 get_response() 方法应该直接返回模拟响应,而不需要调用父类的方法。调整副作用设置以正确迭代模拟响应,并直接从 MockClient 返回模拟响应。
此代码可以工作
test_api_client.py
import unittest
from ApiTest.api_client import MockClient
class TestApiClient(unittest.TestCase):
client = MockClient()
def test_get_response(self):
for i in range(2):
print(f"Iteration {i}: {self.client.get_response()}")
if __name__ == '__main__':
unittest.main()
ApiTest\api_client.py
from typing import Dict
from unittest.mock import Mock, patch
import json
import requests
def mock_response_1() -> dict:
return {"data": {"users": [{"id": "AAA"}]}}
def mock_response_2() -> dict:
return {"data": {"users": [{"id": "BBB"}]}}
def mock_json_response(mocked_json: Dict, status_code: int = 200) -> Mock:
response_mock = Mock()
response_mock.status_code = status_code
response_mock.headers = {"Content-Type": "application/json"}
response_mock.json.return_value = mocked_json
response_mock.text = json.dumps(mocked_json)
return response_mock
class ApiClient:
def get_response(self) -> dict:
request_r = requests.get(url="https://api.test.com")
request_r = request_r.json()
return request_r.get("data")
class MockClient(ApiClient):
def __init__(self):
self.mock_responses = [
mock_response_1(),
mock_response_2()
]
self.response_index = 0
@patch('requests.get')
def get_response(self, mocked_get: Mock):
mocked_get.return_value = mock_json_response(self.mock_responses[self.response_index])
self.response_index = (self.response_index + 1) % len(self.mock_responses)
return super().get_response()
pip install requests unittest
python test_api_client.py
Iteration 0: {'users': [{'id': 'AAA'}]}
Iteration 1: {'users': [{'id': 'BBB'}]}