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

测试时替换函数遇执行顺序问题:Oracle与SQLite查询适配

解决Oracle与SQLite语法差异下的do()方法测试问题

问题根源分析

你遇到的执行顺序混乱、后续函数无法执行的问题,大概率是以下两个原因导致:

  1. patch的目标路径错误,没有正确定位到类的方法
  2. 原代码中do()方法的update()调用漏传了query参数(示例代码里的明显问题)
  3. 多方法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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 20:55:12