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

使用pyTest Mock对象测试get_user_by_username函数时遇TypeError问题求解

问题与解决方案

待测试函数

def get_user_by_username(db, username: str) -> Waiter:
    """根据给定用户名获取用户对象。"""
    user = db.query(Waiter).filter(Waiter.username == username).first()
    return user

错误的测试代码及报错

我尝试Mock数据库调用并返回正确的Waiter对象,编写的测试代码如下:

def test_get_user_by_username(mocker):
    waiter = Waiter(id=10, username="string", password="1111")
    db_mock = mocker.Mock(return_value=waiter)
    result = get_user_by_username(db=db_mock, username="string")
    assert result.json()["username"] == "string"

运行时出现错误:TypeError: 'Mock' object is not subscriptable

正确解决方案

根据@Don Kirkby的回答,正确的测试代码如下:

def test_get_user_by_username(mocker):
    waiter = Waiter(id=10, username="string", password="1111")
    # 逐层Mock链式调用的每个方法
    filter_method = mocker.Mock()
    filter_method.first = mocker.Mock(return_value=waiter)
    query = mocker.Mock()
    query.filter = mocker.Mock(return_value=filter_method)
    db_mock = mocker.Mock()
    db_mock.query = mocker.Mock(return_value=query)
    
    result = get_user_by_username(db=db_mock, username="string")
    # 直接通过对象属性或vars()获取属性值做断言
    assert vars(result)["username"] == "string"
    # 也可以直接断言属性:assert result.username == "string"

错误原因说明

  1. Mock对象不符合链式调用逻辑:原函数中是db.query(...).filter(...).first()的链式调用,直接给db_mock设置return_value无法模拟这一串方法调用,必须逐层Mock每个方法的返回值,让调用链能正确走到first()并返回预设的Waiter对象。
  2. 断言方式错误:Waiter对象通常没有json()方法,即便有,原代码中得到的result可能还是Mock对象而非真实Waiter实例,导致后续下标访问报错。正确做法是直接访问对象属性,或用vars(result)获取属性字典后取值断言。

内容的提问来源于stack exchange,提问作者Vitalii Mytenko

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 13:05:40