讲师中心 微信公众号
AI工具推荐 视频效率加速

如何在 Python 单元测试中正确 Mock 直接导入的函数

浅杰吖_7480

浅杰吖_7480

发布时间:2026-02-04 16:28:03

|

962人浏览过

|

来源于php中文网

原创

如何在 Python 单元测试中正确 Mock 直接导入的函数

当函数以 `from module import func` 方式被导入时,需在**使用该函数的模块作用域内**进行 patch(如 `@patch("entry.read_sql")`),而非原始定义模块,否则 mock 不生效。

在 Python 单元测试(尤其是使用 unittest.mock.patch)中,mock 的目标必须是对象在运行时实际被引用的位置,而非其原始定义位置。这是初学者最容易混淆的关键点。

以你的代码为例:

# entry.py
from sql_services import read_sql  # ← 此处将 read_sql 绑定为 entry 模块的局部名称

def foo():
    df = read_sql("SELECT * FROM schema.table")  # ← 实际调用的是 entry.read_sql!
    return df

虽然 read_sql 定义在 sql_services 中,但 foo() 内部访问的是 entry 模块的全局变量 read_sql —— 这是 Python 导入机制决定的:from ... import 会在当前命名空间创建一个新引用。因此,mock 必须指向 "entry.read_sql",而不是 "sql_services.read_sql"。

✅ 正确的测试写法如下:

Python Hardener
Python Hardener

通过完整的安全审查、代码整洁重构、健壮的错误处理、正确的日志记录以及完整的文档字符串覆盖,强化 Python 脚本。

下载

立即学习“Python免费学习笔记(深入)”;

# test_entry.py
import pytest
import unittest.mock as mock
import pandas as pd

from entry import foo

@mock.patch("entry.read_sql")  # ← 关键:patch 使用方模块中的名称
def test_do_a_read(mock_read_sql):
    mock_read_sql.return_value = pd.DataFrame({"id": [1, 2]})

    result = foo()  # ← 此时调用的是被 mock 的 entry.read_sql

    assert len(result) == 2
    mock_read_sql.assert_called_once_with("SELECT * FROM schema.table")

⚠️ 注意事项:

  • ❌ @patch("sql_services.read_sql") 对 foo() 无效,因为 foo 并未通过 sql_services.read_sql 访问该函数;
  • ✅ Patch 路径必须与 导入后实际使用的全限定名一致(即 module_name.object_name);
  • 若 entry.py 中存在多个导入(如 from sql_services import read_sql, write_sql),需分别 patch entry.read_sql 和 entry.write_sql;
  • 使用 pytest 时,也可改用 monkeypatch fixture 实现更灵活的局部 mock(适合复杂场景),但 @patch 仍是标准、清晰的首选。

? 小技巧:可通过 print(entry.read_sql) 或 assert entry.read_sql is not sql_services.read_sql 验证导入是否创建了独立引用,加深理解。

总结:Mock 的本质是“替换运行时符号表中的对象”,不是“替换源码定义”。始终 patch 被测试代码所在模块中该符号的名称,即可避免因导入方式不同导致的 mock 失效问题。

热门AI工具

更多
小橡皮AI

一款AI工具,主要用于小橡皮一键去AI味,将机器味重的内容改得更有活人感,防止因为 AI 内容被平台打上 AI 标签,以及限流,适合需要提升相关任务效率的用户。

Flowith
Flowith Hot

Flowith是一款基于画布和智能体工作流的 AI 协作工作空间。

Seko
Seko Hot

一款AI视频创作工具,主要用于商汤科技推出的创编一体的AI短视频创作Agent,适合需要提升相关任务效率的用户。

UP简历
UP简历 Hot

一款AI办公效率工具,主要用于基于AI技术的免费在线简历制作工具,适合需要提升相关任务效率的用户。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

火山引擎

火山引擎是一款面向企业的云计算与AI服务平台。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

创客贴AI

创客贴AI是一款AI图像与设计工具,AI辅助的智能在线设计工具。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

相关专题

更多
python中print函数的用法
python中print函数的用法

python中print函数的语法是“print(value1, value2, ..., sep=' ', end=' ', file=sys.stdout, flush=False)”。本专题为大家提供print相关的文章、下载、课程内容,供大家免费下载体验。

3320

2023.09.27

python print用法与作用
python print用法与作用

本专题整合了python print的用法、作用、函数功能相关内容,阅读专题下面的文章了解更多详细教程。

269

2026.02.03

全局变量怎么定义
全局变量怎么定义

本专题整合了全局变量相关内容,阅读专题下面的文章了解更多详细内容。

5105

2025.09.18

python 全局变量
python 全局变量

本专题整合了python中全局变量定义相关教程,阅读专题下面的文章了解更多详细内容。

2150

2025.09.18

c++ 全局变量
c++ 全局变量

本专题整合了c++全局变量的使用、定义、作用域等等内容,阅读专题下面的文章了解更多详细内容。

199

2026.03.17

Postman身份认证怎么配置
Postman身份认证怎么配置

本专题从实际API接口调试场景出发,讲解Postman身份认证的完整配置流程,包括常见认证协议介绍、授权参数设置、访问令牌填写、OAuth 2.0授权及认证失败排查,帮助用户正确完成接口授权与访问验证。

0

2026.11.06

Postman请求头Headers怎么设置
Postman请求头Headers怎么设置

围绕Postman HTTP请求头配置展开,讲解Headers选项的具体使用方式,包括Key和Value参数填写、请求头信息添加、常见Header字段设置及请求头修改方法,帮助用户解决接口调试过程中遇到的请求头配置问题。

0

2026.11.06

Postman接口请求发送教程
Postman接口请求发送教程

详细介绍Postman接口请求的创建与发送方法,涵盖GET和POST请求、URL配置、请求参数、Headers请求头、Body请求体设置以及响应结果查看,帮助用户掌握Postman接口请求的完整操作流程。

0

2026.11.06

DBeaver怎么导入数据
DBeaver怎么导入数据

DBeaver数据导入专题,整理Excel、CSV、SQL、TXT等常见文件的数据导入方法,涵盖目标数据库选择、数据表创建、字段映射、数据类型设置及导入参数配置等操作,帮助用户将本地文件中的数据写入数据库,并了解批量导入、重复数据处理和导入失败等常见问题的解决方法。

20

2026.11.05

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn