Monkeypatch Mock httpx外部请求后,接口未修改返回结果求助
排查Sanic接口模拟外部请求后未添加指定字段的问题
以下是几个可能导致问题的原因及对应的解决方法:
1. 模拟的httpx.AsyncClient.get返回值结构错误
httpx.AsyncClient.get实际返回的是**httpx.Response对象**,而非直接的字典。如果你的测试代码直接让模拟方法返回{"response": "response"},接口代码中调用response.json()时会抛出异常,但从你描述的现象来看,更可能是你误将模拟的字典直接返回,跳过了后续添加字段的逻辑。
正确的模拟方式应该返回带有异步json()方法的Mock对象:
async def mock_get(*args, **kwargs): class MockResponse: async def json(self): return {"response": "response"} return MockResponse() monkeypatch.setattr(httpx.AsyncClient, 'get', mock_get)
2. 接口代码中添加字段的逻辑存在疏漏
检查你的接口实现,确认是否正确保存了修改后的字典并返回:
- 错误示例1:修改临时对象后未保存
# 错误:修改的是response.json()返回的临时字典,未赋值给变量 await response.json()['foo'] = 0 return json(await response.json())
- 错误示例2:返回原始数据而非修改后的字典
data = await response.json() data['foo'] = 0 return json(await response.json()) # 这里又重新获取了原始数据
正确的写法应该是:
data = await response.json() data['foo'] = 0 return json(data)
3. Monkeypatch的时机或目标对象错误
确保你是在创建Sanic测试客户端之前完成的Monkeypatch操作,否则实例化的AsyncClient不会使用补丁后的方法。另外,确认补丁的是httpx.AsyncClient.get(类方法),而非实例的get方法——只要补丁在实例化前完成,类方法的补丁会作用于所有新创建的实例。
验证步骤
- 在接口代码中打印
data变量,确认'foo':0是否已被正确添加; - 在测试代码中检查Mock对象的结构,确保
json()方法能返回预期字典; - 确认Monkeypatch操作在测试客户端初始化前执行。
参考示例代码
接口实现
from sanic import Sanic, json import httpx app = Sanic("TestApp") @app.get('/test') async def test_handler(request): async with httpx.AsyncClient() as client: resp = await client.get("https://jsonplaceholder.typicode.com/todos/1") data = await resp.json() data['foo'] = 0 return json(data)
测试代码
import pytest from sanic.testing import TestClient from your_app import app import httpx @pytest.mark.asyncio async def test_test_endpoint(monkeypatch): async def mock_get(*args, **kwargs): class MockResponse: async def json(self): return {"response": "response"} return MockResponse() monkeypatch.setattr(httpx.AsyncClient, 'get', mock_get) async with TestClient(app) as client: resp = await client.get('/test') data = await resp.json() assert data == {"response": "response", "foo": 0}
内容的提问来源于stack exchange,提问作者srbssv
相关产品推荐
相关产品推荐

