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

如何使用pytest-mock模拟Python中的链式函数调用?

链式调用Mock解决方案

错误原因

你之前自己创建的独立MagicMock实例没有和实际业务代码里引用的app.Application绑定,所以业务代码调用时根本不会走到你定义的mock逻辑,自然不生效。

正确实现方案

对于Application.objects(id=xxx).first()这类两层链式调用,只需要给objects方法的返回值绑定first方法的mock返回值即可,代码如下:

def test_update_application(client, mocker):
    # 构造假的Application实例
    test_application = Application(
        id=4, 
        jobTitle='fakeJob12345', 
        companyName='fakeCompany', 
        date=str(datetime.date(2021, 9, 22))
    )
    # 1. Mock Application.objects方法
    mock_objects = mocker.patch('app.Application.objects')
    # 2. 给objects调用后的返回值,设置first方法的返回值为假实例
    mock_objects.return_value.first.return_value = test_application
    # 3. 可选:Mock后续的application.update方法
    mock_update = mocker.patch.object(test_application, 'update')

    # 发起请求
    rv = client.put('/application', json={
        'application':{
            'id':2, 
            'jobTitle':'fakeJob12345', 
            'companyName':'fakeCompany', 
            'date':str(datetime.date(2021, 9, 23)), 
            'status':'1'
        }
    })
    # 校验逻辑
    print(rv.data)
    # 注:你粘贴的原接口代码有截断,需确保接口成功分支返回了对应结构,再调整断言即可
    jdata = json.loads(rv.data.decode("utf-8"))["jobTitle"]
    assert jdata == 'fakeJob12345'
    # 额外可选校验:update方法是否按入参调用
    mock_update.assert_called_once_with(
        jobTitle='fakeJob12345',
        companyName='fakeCompany',
        date=str(datetime.date(2021, 9, 23)),
        status='1'
    )

原理解释

  • 调用mocker.patch('app.Application.objects')时,返回的mock_objects就是对Application.objects方法的mock对象
  • mock_objects.return_value对应Application.objects(id=xxx)调用完成后的返回值
  • 再给这个返回值的first方法设置return_value,就对应Application.objects(id=xxx).first()的返回值
  • 如果是更长的链式调用,比如a.b().c().d(),只要依次给每一层的return_value的下一个方法设置返回值即可

内容的提问来源于stack exchange,提问作者Setu Kumar Basak

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 09:45:08