pytest使用MagicMock模拟返回值时提示缺少位置参数问题
问题根因
这个报错和MagicMock的机制理解偏差没关系,是两个写法错误导致的:
- 首先是patch路径完全不匹配,mock根本没生效。你在测试文件头部通过
from package.module2 import get_database_connection把函数直接导入到当前测试模块的命名空间下调用,但你patch的目标是package.module.get_database_connection,这个替换操作根本碰不到你当前测试文件里引用的真实get_database_connection函数。你运行测试时调用的还是原始函数,这个函数本身要求传入parameter1位置参数,你没传自然会抛出对应的缺参错误。
你提到的「patch要填函数被调用的位置,不是定义位置」的规则是完全正确的,你现在恰恰违反了这个规则:你在测试函数里直接调用get_database_connection,这个引用的查找范围是当前测试模块的命名空间,和package.module没有关系。 - 其次,就算你把patch路径改对了,当前配置的
return_value也通不过后续断言。你现在写的返回值是字符串类型的数据库连接串,根本不是pyodbc.Connection类型的实例,第二个类型判断断言必然失败。
修正方案
- 把patch的目标路径改成实际调用该函数的命名空间路径。如果你当前的测试文件名为
test_db.py,那么测试模块的引用名就是test_db,patch路径要写成test_db.get_database_connection;如果后续你要测试其他业务模块里调用get_database_connection的逻辑,再把patch路径替换成对应业务模块下的引用路径即可。 - 把mock的返回值配置为符合
pyodbc.Connection规范的Mock对象,不要直接返回连接字符串。
修正后的可运行测试代码如下:
import pyodbc from unittest.mock import patch, MagicMock from package.module2 import get_database_connection # 请把test_db替换为你当前测试文件的实际文件名(不带.py后缀) @patch("test_db.get_database_connection") def test_get_database_connection(mock_get_conn): # 构造符合pyodbc.Connection类型的mock连接对象 mock_conn = MagicMock(spec=pyodbc.Connection) mock_get_conn.return_value = mock_conn conn = get_database_connection() assert conn is not None assert isinstance(conn, pyodbc.Connection)
如果你习惯在patch装饰器上直接传入预配置的MagicMock,也可以用下面的写法,核心还是路径必须匹配:
@patch( "test_db.get_database_connection", MagicMock(return_value=MagicMock(spec=pyodbc.Connection)) ) def test_get_database_connection(): conn = get_database_connection() assert conn is not None assert isinstance(conn, pyodbc.Connection)
补充说明
patch的核心判断逻辑永远不变:哪个模块的代码执行时会调用这个被mock的对象,就patch哪个模块命名空间下的对应引用。比如后续你要测试package.module里的业务函数,这个函数内部调用了get_database_connection,那时候patch路径写package.module.get_database_connection才是正确的。
内容的提问来源于stack exchange,提问作者FreyGeospatial
相关产品推荐
相关产品推荐

