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

使用Pytest测试异步方法时,被补丁方法的调用次数未正确统计

问题分析与解决方案

你的问题核心是:mock对象的call_count未正确更新,但实际代码中确实调用了get_item方法,且模拟返回值生效。这几乎可以确定是mock路径不匹配导致的——你patch的对象与中间件实际使用的table不是同一个引用。

关键原因

假设你的CacheMiddleware代码中是这样导入table的:

# api/utils/cache_middleware.py
from api.utils.dynamo import table

class CacheMiddleware:
    async def dispatch(self, request, call_next):
        # 使用 table.get_item(...)

此时,cache_middleware模块会在导入时创建一个对dynamo.table的本地引用。而你当前fixture中patch的是api.utils.cache_middleware.dynamo.table——这仅修改了dynamo模块里的table,但cache_middleware模块里的本地引用还是原来的table对象,所以中间件实际调用的是未被mock的原始对象,你断言的却是新mock的对象,自然call_count为0。

解决方案

修改fixture中的patch路径,直接patchcache_middleware模块里的本地table引用:

@pytest.fixture(scope="function", name="cache_service_table_get_mock")
def fixture_cache_service_table_get_mock(mocker: MockerFixture):
    # 改为patch中间件模块内的table引用
    mock_table = mocker.patch("api.utils.cache_middleware.table")

    mock_table.get_item.return_value = {"Items": []}
    mock_table.put_item.return_value = None

    yield mock_table

验证方法

可以在测试函数中添加打印,确认mock对象与中间件使用的对象是否为同一个:

@pytest.mark.asyncio
async def test_cache_no_hit(cache_service_table_get_mock: MagicMock):
    from api.utils.cache_middleware import table as middleware_table
    # 打印两个对象的内存地址,若相同则路径正确
    print(f"Mock table ID: {id(cache_service_table_get_mock)}")
    print(f"Middleware table ID: {id(middleware_table)}")
    
    # 原有测试代码...

额外注意点

如果get_item是异步方法,建议用AsyncMock替代MagicMock,确保mock返回可等待对象:

from unittest.mock import AsyncMock

@pytest.fixture(scope="function", name="cache_service_table_get_mock")
def fixture_cache_service_table_get_mock(mocker: MockerFixture):
    mock_table = mocker.patch("api.utils.cache_middleware.table", new_callable=AsyncMock)
    mock_table.get_item.return_value = {"Items": []}
    mock_table.put_item.return_value = None
    yield mock_table

内容的提问来源于stack exchange,提问作者Jesus Diaz Rivero

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 19:08:09