如何通过MockerFixture正确异步Mock Document类的find_one方法?
如何通过MockerFixture正确异步Mock Document类的find_one方法?
我来帮你梳理这个问题的原因和解决办法,你遇到的坑其实是异步方法mock的典型问题,咱们一步步来:
首先,先分析你之前的两个错误:
- patch FindInterface没生效:因为你代码里实际调用的是
MyDocument.find_one(),如果MyDocument的find_one没有直接绑定到FindInterface的实现,或者你的patch路径不对,mock就不会覆盖到实际执行的方法,所以真实的find_one还是会返回None,触发你的错误。 - patch MyDocument报错“不能在await表达式中使用类型”:这是因为你直接把
find_one替换成了get_my_document()的返回值(也就是一个MyDocument实例),而不是一个可调用的异步函数。await后面必须跟可await的对象(比如异步函数、协程对象),直接await一个实例肯定会报错。
正确的解决思路
因为find_one是异步方法,所以你的mock必须满足两个条件:
- 指向正确的目标(也就是
MyDocument类的find_one方法) - 是一个可await的对象(要么用
AsyncMock,要么是自定义的异步函数)
具体实现方案
下面给你两种常用的正确写法:
方案一:用AsyncMock(推荐,最简洁)
pytest-mock的mocker已经集成了AsyncMock,可以直接用来创建异步方法的mock,指定它的返回值为你想要的文档实例:
# 先定义你的测试数据生成函数 def get_my_document(): return MyDocument(name="test_doc", created=datetime.now(), desc="test description") def test_your_endpoint(mocker): # 用AsyncMock来mock MyDocument的find_one方法,并指定返回值 mock_find_one = mocker.patch.object(MyDocument, "find_one", mocker.AsyncMock(return_value=get_my_document())) # 执行你的endpoint测试逻辑,比如调用接口函数 # response = await client.get("/your-endpoint") # 还可以验证mock是否被调用过 mock_find_one.assert_awaited_once()
方案二:用自定义异步函数作为mock
如果你想自己控制mock的逻辑(比如根据不同参数返回不同结果),可以写一个异步函数来替换find_one:
async def mock_find_one(query=None): # 这里可以加自定义逻辑,比如根据查询参数返回不同内容 if query and query.get("name") == "test_doc": return MyDocument(name="test_doc", created=datetime.now(), desc="test description") return None def test_your_endpoint(mocker): # 把MyDocument的find_one替换成自定义的异步函数 mocker.patch.object(MyDocument, "find_one", mock_find_one) # 执行测试逻辑...
额外提醒
如果你的find_one需要接收查询参数,还可以用side_effect来处理更复杂的场景,比如:
def test_with_query_params(mocker): mock_find_one = mocker.patch.object(MyDocument, "find_one", mocker.AsyncMock()) # 根据不同的查询参数返回不同结果 def mock_side_effect(query): if query == {"name": "test"}: return get_my_document() return None # 注意:side_effect如果是普通函数,AsyncMock会自动把它包装成异步的 mock_find_one.side_effect = mock_side_effect # 执行测试...
这样就能正确mock异步的find_one方法,不会再出现找不到文档或者await报错的问题啦!
备注:内容来源于stack exchange,提问作者1llya
相关产品推荐
相关产品推荐

