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

Python Unittest中Mock cursor.fetchall()报错,如何正确模拟返回值?

问题描述

对main_func执行集成测试时,尝试Mock cursor.fetchall()以返回模拟值,触发错误:

ModuleNotFoundError: No module named 'src.utils.cursor'; 'src.utils' is not a package

项目结构:

--project 
  --src 
    --tests 
      --test_main.py 
    --main.py 
    --utils.py

相关代码:

utils.py

def update_configuration(configuration, mysql_client):
    query = "SELECT * from some database"
    cursor = mysql_client.execute_query(query)
    function_mapping = cursor.fetchall()
    cursor.close()
    configuration["mapping"] = {}
    for (display_name, formula_name) in function_mapping:
        configuration["formula_mapping"][formula_name] = display_name

main.py

def main_func(configuration): 
    mysql_client = get_mysql_connection() 
    ut.update_configuration(configuration, mysql_client) # ut 指代 utils.py

test_main.py(原test.py)

@mock.patch("src.utils.cursor.fetchall",return_value = [1,2,3,4])  
@mock.patch("src.main.get_sql_connection", return_value = mock.Mock()) 
def test_initiate_calc(self, dummy1): 
    # 对 main_func 执行集成测试

需求:找到正确的Mock方式,让function_mapping = cursor.fetchall()能获取指定返回值。

解决方案

错误核心是你Mock的路径src.utils.cursor不存在——cursor并非src.utils模块的静态对象,而是mysql_client.execute_query()运行时返回的实例对象,无法直接通过模块路径Mock。正确思路是Mock依赖链上的可寻址对象,逐层控制cursor.fetchall()的返回值:

修改后的测试代码

@mock.patch("src.main.get_mysql_connection")
def test_initiate_calc(self, mock_mysql_conn):
    # 1. 创建Mock cursor,指定fetchall返回符合业务逻辑的结构
    mock_cursor = mock.Mock()
    mock_cursor.fetchall.return_value = [("display_name_1", "formula_name_1"), ("display_name_2", "formula_name_2")]
    
    # 2. 让mysql客户端的execute_query方法返回这个mock cursor
    mock_mysql_conn.return_value.execute_query.return_value = mock_cursor

    # 3. 准备测试用配置
    test_config = {"formula_mapping": {}}

    # 4. 执行被测试函数
    main_func(test_config)

    # 5. 可选:验证逻辑正确性
    assert test_config["formula_mapping"] == {"formula_name_1": "display_name_1", "formula_name_2": "display_name_2"}
    mock_cursor.close.assert_called_once()

关键说明

  • 放弃Mocksrc.utils.cursor.fetchall,因为cursor是动态生成的实例,mock.patch只能作用于模块、类、实例属性等可通过路径寻址的对象。
  • 从上游依赖开始Mock:main_func依赖get_mysql_connection返回的客户端,客户端的execute_query返回cursor,因此逐层Mock这些对象的行为,最终控制fetchall()的返回值。
  • 原测试中的get_sql_connection应为笔误,需修正为get_mysql_connection,保证与main.py中的调用一致。

内容的提问来源于stack exchange,提问作者Just another object

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 10:36:59