测试时替换函数遇执行顺序问题:Oracle与SQLite查询适配
解决Oracle与SQLite语法差异下的do()方法测试问题
问题根源分析
你遇到的执行顺序混乱、后续函数无法执行的问题,大概率是以下两个原因导致:
patch的目标路径错误,没有正确定位到类的方法- 原代码中
do()方法的update()调用漏传了query参数(示例代码里的明显问题) - 多方法
patch时作用域或调用逻辑冲突
修正后的类代码
首先修复do()方法的参数传递问题:
class MyClass: def get_insert_query(self): return "insert .... where my_date > sysdate" def insert(self, query): # 实际插入逻辑 pass def get_update_query(self): return "update .... where my_date > sysdate" def update(self, query): # 实际更新逻辑 pass def do(self): query = self.get_insert_query() self.insert(query) query = self.get_update_query() self.update(query) # 补充漏传的query参数
正确的测试用例实现
使用unittest.mock.patch同时替换两个查询方法,确保语法适配SQLite:
方式1:多装饰器顺序patch
import unittest from unittest.mock import patch from your_module import MyClass # 替换为你的类所在模块路径 class TestMyClassDo(unittest.TestCase): # 注意装饰器顺序:最下面的patch对应第一个测试参数 @patch('your_module.MyClass.get_update_query') @patch('your_module.MyClass.get_insert_query') def test_do(self, mock_insert_query, mock_update_query): # 设置SQLite适配的查询语句 mock_insert_query.return_value = "insert .... where my_date > datetime('now')" mock_update_query.return_value = "update .... where my_date > datetime('now')" # 执行测试逻辑 obj = MyClass() obj.do() # 验证调用是否符合预期 mock_insert_query.assert_called_once() mock_update_query.assert_called_once() obj.insert.assert_called_once_with("insert .... where my_date > datetime('now')") obj.update.assert_called_once_with("update .... where my_date > datetime('now')")
方式2:使用patch.multiple简化多方法替换
import unittest from unittest.mock import patch from your_module import MyClass class TestMyClassDo(unittest.TestCase): @patch.multiple('your_module.MyClass', get_insert_query=lambda self: "insert .... where my_date > datetime('now')", get_update_query=lambda self: "update .... where my_date > datetime('now')") def test_do(self): obj = MyClass() obj.do() # 验证逻辑同方式1 self.assertEqual(obj.insert.call_count, 1) self.assertEqual(obj.update.call_count, 1)
关键注意事项
- patch路径必须正确:要使用测试代码中
MyClass被导入的路径,而非类定义的原始路径(比如测试文件和类文件同目录时,路径为your_module.MyClass.get_insert_query) - 验证调用顺序:如果担心执行顺序混乱,可以用
mock_insert_query.call_args_list查看调用时序,确保get_insert_query先于get_update_query被调用 - 避免mock冲突:如果测试用例较多,建议在
setUp或tearDown中管理mock的创建与销毁,防止跨用例干扰
内容的提问来源于stack exchange,提问作者elyes massoussi
相关产品推荐
相关产品推荐

