如何通过本地JSON文件Mock Python API调用实现单元测试?
用本地Mock JSON完成API依赖函数的单元测试
你的思路完全正确——通过Mock替代真实API调用,用本地JSON文件模拟响应,既能避免网络依赖保证测试稳定性,又能精准验证函数的业务处理逻辑。下面针对你的代码给出修正和优化方案:
先修正代码里的几个关键问题
- 补全缺失依赖:原代码中
get_replication_policies_list用到了requests但未导入,必须补上 - 修正Patch路径:
@patch装饰器里的module_name要替换成你实际的Python文件名(比如代码在api_utils.py里,就写api_utils.ApiContextRetrieval.get_replication_policies_list) - 对齐JSON结构:本地
application_jq_used.json的结构必须和真实API返回一致,确保是包含name和id字段的对象数组
修正后的完整代码
import json import unittest import requests # 补全缺失的导入 from unittest.mock import patch class ApiContextRetrieval: def __init__(self, search_word): self.replication_rule_name = search_word self.policy_id = None def find_policy_id(self): replication_policies_list = self.get_replication_policies_list() for replication_name in replication_policies_list: if replication_name["name"] == self.replication_rule_name: self.policy_id = replication_name["id"] break def get_replication_policies_list(self): url = "https://example.com/api/......." headers = {"accept": "application/json", "authorization": "Bearer TOKEN"} response = requests.get(url, headers=headers) response.raise_for_status() # 新增:处理API请求失败的场景 return response.json() class TestApiContextRetrieval(unittest.TestCase): def setUp(self): self.search_word = "rule" self.policy_id_of_replication = 50 # 将JSON加载移到setUp,避免测试方法重复代码 try: with open("application_jq_used.json") as file: self.mock_replication_policies = json.load(file) except FileNotFoundError: self.fail("测试用JSON文件不存在,请检查路径") @patch("api_utils.ApiContextRetrieval.get_replication_policies_list") # 替换为实际模块名 def test_find_policy_id_matches(self, mock_get_policies): mock_get_policies.return_value = self.mock_replication_policies api_context = ApiContextRetrieval(self.search_word) api_context.find_policy_id() # 验证结果正确 self.assertEqual(api_context.policy_id, self.policy_id_of_replication) # 验证Mock方法确实被调用一次 mock_get_policies.assert_called_once() @patch("api_utils.ApiContextRetrieval.get_replication_policies_list") def test_find_policy_id_no_match(self, mock_get_policies): # 构造无匹配项的Mock数据 mock_data = [{"name": "other_rule", "id": 100}] mock_get_policies.return_value = mock_data api_context = ApiContextRetrieval("non_existent_rule") api_context.find_policy_id() # 验证未找到时policy_id保持None self.assertIsNone(api_context.policy_id) if __name__ == "__main__": unittest.main()
关键优化点说明
- 集中加载JSON:把JSON文件的加载逻辑移到
setUp方法,避免每个测试方法重复写文件操作,提升代码维护性 - 完善异常处理:在
get_replication_policies_list中加入response.raise_for_status(),确保API请求失败时抛出异常,后续也可以针对异常场景编写测试用例 - 补充边界测试:新增
test_find_policy_id_no_match用例,验证当没有匹配规则时的逻辑正确性,覆盖更多业务场景 - 验证Mock调用:用
assert_called_once()确保Mock方法被正确触发,避免测试逻辑遗漏关键步骤
额外实践建议
- 把测试用的JSON文件放在专门的测试资源目录(比如
tests/fixtures/),方便统一管理测试数据 - 如果需要多个不同结构的Mock数据,可以为每个测试用例单独加载对应JSON,或在
setUp中加载多份数据
内容的提问来源于stack exchange,提问作者Aherontas
相关产品推荐
相关产品推荐

