pytest-asyncio-httpx-mocking
When masking httpx.AsyncClient with unittest.mock in Pytest, AsyncMock must be used instead of MagicMock for async methods like post/get to prevent TypeError when awaited.
适合你,如果在测试异步HTTP客户端时遇到类型错误
/ 下载安装
/ 通过 npx 安装 校验哈希
npx oh-my-skill add project-n-e-k-o/n.e.k.o/pytest-asyncio-httpx-mocking/ 通过 bash 安装
curl -fsSL https://oh-my-skill.com/install.sh | bash -s -- project-n-e-k-o/n.e.k.o/pytest-asyncio-httpx-mocking/ 已经装过?验证本机副本,不用重装
npx oh-my-skill verify project-n-e-k-o/n.e.k.o/pytest-asyncio-httpx-mocking安装目标可用 --agent / --scope 或 --to 明确指定;省略时只会在唯一已存在的 agent 目录上自动选择,零命中或多命中会停止并提示。content_hash 缺失或不一致均拒装。
2258GitHub stars
~568上下文体积 · 单文件
索引托管
怎么用
商店整理自技能原文 · 版本 b0c3c15 · 表述以原文为准它做什么
当用户要求生成或调试使用 pytest 和 httpx.AsyncClient 的测试代码时,Claude 会自动使用 AsyncMock 来模拟异步方法(如 post/get),避免 TypeError,并提供正确的代码示例。
什么时候触发
用户提及模拟 httpx.AsyncClient、pytest 测试中遇到 await 相关 TypeError,或请求编写异步 HTTP 客户端测试代码时触发。
装好后可以这样说
会提供使用AsyncMock的正确代码示例
技能原文 SKILL.md
httpx.AsyncClient Mocking with AsyncMock
症状
- 在测试中使用
patch.object(httpx.AsyncClient, 'post', return_value=mock_response)。 - 运行时,代码中包含
response = await client.post(...)的地方抛出TypeError: object MagicMock can't be used in 'await' expression。
根本原因
原因 1: 异步函数的返回值必须是 Coroutine
- 问题:
httpx.AsyncClient.post是一个async def方法,调用它会返回一个可等待(awaitable)的协程。 - 为什么发生: 默认的
patch或MagicMock没有自动推断对象的异步特性时,它只是同步地返回了return_value。当事件循环试图await这个同步的MagicMock对象时,就会报错。 - 解决方案: 在
patch参数里显式使用new=AsyncMock(return_value=...)或new_callable=AsyncMock。
代码解决方案
❌ 错误写法:
from unittest.mock import patch, MagicMock
mock_response = MagicMock(status_code=200)
# 当被 await 时会触发 TypeError!
with patch.object(httpx.AsyncClient, 'post', return_value=mock_response):
await my_crawler.fetch()
✅ 正确写法:
from unittest.mock import patch, MagicMock, AsyncMock
mock_response = MagicMock(status_code=200) # Response 对象本身及其方法通常是同步的
# 正确!覆盖掉原来的方法,使其行为成为一个 AsyncMock
with patch.object(httpx.AsyncClient, 'post', new=AsyncMock(return_value=mock_response)):
await my_crawler.fetch()
使用 side_effect 模拟循序多次请求:
with patch.object(httpx.AsyncClient, 'get', new=AsyncMock(side_effect=[mock_1, mock_2])):
...
关键经验
- 针对任何
async def的 Mock,必须保证它被调用时能走协程语境。 - 严格区分 异步的请求方法 与 同步的响应对象:
httpx.AsyncClient.get是异步的(需AsyncMock),但它返回的Response对象上的.json()是同步的(需MagicMock即可)。
按 Apache-2.0 许可原样转载,未经改动 · 在 GitHub 查看 →
评论
登录即可评论;带「已验证安装」的,是发布者名下有本店的安装或持有记录。
…