Python嵌套函数单元测试报错:MagicMock实例间不支持'>'运算
问题解决方法
错误原因
报错TypeError: '>' not supported between instances of MagicMock and MagicMock的核心原因有三个:
- Patch路径错误:你patch的是原始模块的函数,而非被测试函数所在模块中导入的函数引用,导致mock未生效,
max_date或transformed_dataframe变成MagicMock实例。 - 未Mock所有依赖函数:
modify_df和write_to_db未被打桩,前者返回MagicMock导致后续列操作生成Mock对象,后者会触发实际数据库写入。 - 断言写法错误:
assert_called是属性而非方法,不会执行断言校验。
修正步骤
1. 修正Patch路径
假设你的update_func位于my_module.py中,需要patch该模块内导入的函数引用,而非原始模块:
- 原
@patch('file1.get_cutover_date')改为@patch('my_module.file1.get_cutover_date') - 原
@patch('file2.get_dataframe_from_db')改为@patch('my_module.file2.get_dataframe_from_db')
2. Mock剩余依赖函数
新增对modify_df和write_to_db的patch,确保它们返回可控对象:
- 如果
modify_df是当前模块函数,patchmy_module.modify_df,让它直接返回传入的DataFrame(或自定义测试DataFrame) - 如果
write_to_db是当前模块函数,patchmy_module.write_to_db,避免实际写入数据库
3. 修正断言写法
将patched_get_cutover.assert_called改为patched_get_cutover.assert_called_once(),patched_get_df.assert_called改为patched_get_df.assert_called_once_with('test_query'),确保断言生效。
修改后的测试代码示例
from unittest.mock import patch from pyspark.sql import Row, SparkSession import my_module # 导入你的update_func所在模块 spark = SparkSession.builder.master("local").appName("test").getOrCreate() @patch('my_module.write_to_db') @patch('my_module.modify_df') @patch('my_module.file2.get_dataframe_from_db') @patch('my_module.file1.get_cutover_date') def test_update_func(patched_get_cutover, patched_get_df, patched_modify_df, patched_write_db): # Mock cutover日期 patched_get_cutover.return_value = '2015-01-01 00:00:00' # 构造测试DataFrame response = [Row(id=1, date='2016-10-12 00:00:00')] response_df = spark.createDataFrame(response) # Mock数据库读取和数据转换 patched_get_df.return_value = response_df patched_modify_df.return_value = response_df # 直接返回原始DF,或自定义转换后的DF # 执行测试函数 my_module.update_func('test_query') # 断言mock被正确调用 patched_get_cutover.assert_called_once() patched_get_df.assert_called_once_with('test_query') patched_modify_df.assert_called_once_with(response_df) patched_write_db.assert_called_once()
内容的提问来源于stack exchange,提问作者RedFox
相关产品推荐
相关产品推荐

