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

Pytest使用monkeypatch模拟API调用时如何根据不同输入返回不同响应

解决方案

核心问题原因

  • 你之前的代码在调用monkeypatch.setattr时,直接执行了mock_res(data_entry),把函数返回值传给了被mock的get_data,而monkeypatch.setattr要求第三个参数传入可调用对象,这是代码不生效的核心原因。
  • MockResponse的结构可以根据实际需求简化,不需要额外嵌套静态方法也能实现需求。

实现方案

方案1:根据被mock函数的入参自动返回对应响应

如果你的api_funct.get_data调用时的入参可以和要返回的value_1、value_2一一对应,直接让mock函数判断入参返回对应值即可:

import pytest
from xxx import api_funct # 导入你实际的api模块

value_1 = {'key1': 'value1', 'key2': 'value2', 'key3': 'value3'}
value_2 = {'key11': 'value11', 'key22': 'value22', 'key33': 'value33'}

# 模拟响应对象,如果你原get_data返回的是响应对象需要调用.json()就保留,不需要的话可以直接返回字典
class MockResponse:
    def __init__(self, json_data):
        self._json_data = json_data
    def json(self):
        return self._json_data

def test_dynamic_response(monkeypatch):
    def mock_get_data(*args, **kwargs):
        # 这里args是get_data调用时的位置参数,kwargs是关键字参数,根据实际入参判断返回值
        # 举个例子:如果调用get_data("type1")就返回value_1,调用get_data("type2")返回value_2
        if args[0] == "type1":
            return MockResponse(value_1)
        elif args[0] == "type2":
            return MockResponse(value_2)
        else:
            return MockResponse(load_data("total_res.json"))
    
    monkeypatch.setattr(api_funct, "get_data", mock_get_data)
    
    # 接下来写你的测试逻辑即可,不同入参调用get_data会返回对应响应

方案2:for循环遍历测试场景,动态设置mock返回值

如果你是在参数化测试/for循环里,每个测试场景固定返回某个值,可以用闭包生成对应的mock函数:

def test_loop_response(monkeypatch):
    # 你的测试场景列表:(入参, 预期返回值)
    test_cases = [
        ("input1", value_1),
        ("input2", value_2),
        ("default_input", load_data("total_res.json"))
    ]

    for input_param, expect_res in test_cases:
        # 生成当前场景对应的mock函数
        def mock_get_data(*args, **kwargs):
            return MockResponse(expect_res)
        
        monkeypatch.setattr(api_funct, "get_data", mock_get_data)
        
        # 执行当前场景的测试逻辑
        result = 你要测试的函数(input_param)
        # 这里写断言逻辑
        assert ...

快速修复你原来的写法

如果要保留你原来的代码结构,只要改setattr的部分即可,把直接调用改成传闭包:

data_entry = "value_1" # 你需要的响应类型
# 用闭包捕获当前的data_entry变量
def mock_res(*args, **kwargs):
    return MockResponse().json(data_entry)

monkeypatch.setattr(api_funct, "get_data", mock_res)

内容的提问来源于stack exchange,提问作者hungry_in_learning

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 06:36:04