You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过本地JSON文件Mock Python API调用实现单元测试?

用本地Mock JSON完成API依赖函数的单元测试

你的思路完全正确——通过Mock替代真实API调用,用本地JSON文件模拟响应,既能避免网络依赖保证测试稳定性,又能精准验证函数的业务处理逻辑。下面针对你的代码给出修正和优化方案:

先修正代码里的几个关键问题

  1. 补全缺失依赖:原代码中get_replication_policies_list用到了requests但未导入,必须补上
  2. 修正Patch路径:@patch装饰器里的module_name要替换成你实际的Python文件名(比如代码在api_utils.py里,就写api_utils.ApiContextRetrieval.get_replication_policies_list)
  3. 对齐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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 13:52:45