如何在Python2.7中用mock库模拟Connection的cursor.execute()调用并验证参数?
在Python 2.7环境下,咱们得用单独的mock第三方库(毕竟Python2.7没内置Python3里的unittest.mock)来实现这个需求。我给你拆解成一步步的实操方案,保证能搞定验证cursor.execute()调用参数的问题:
步骤1:先安装mock库
因为Python2.7没有内置mock模块,所以先通过pip安装:
pip install mock
步骤2:核心思路梳理
要验证cursor.execute()的调用,咱们需要做这几件事:
- 桩化数据库连接对象(Connection),让它返回一个被监控的cursor对象
- 给这个cursor的
execute方法做桩化,这样就能追踪它的调用次数、传入参数 - 运行你要测试的业务代码(也就是会触发
cursor.execute()的代码) - 最后验证
execute是否按预期被调用,SQL语句和参数格式是否正确
步骤3:具体代码示例
假设你有一段业务代码在db_utils.py里,逻辑是传入连接和用户ID,执行查询:
# db_utils.py def get_user_details(conn, user_id): cursor = conn.cursor() # 这里是我们要验证的execute调用 cursor.execute("SELECT name, email FROM users WHERE id = %s", (user_id,)) return cursor.fetchone()
接下来写测试用例,用Python2.7的unittest配合mock:
import unittest from mock import Mock, patch import db_utils class TestDBUtils(unittest.TestCase): def test_get_user_details_executes_correct_sql(self): # 1. 创建桩化的Cursor和Connection对象 mock_cursor = Mock() # 这个cursor的所有操作都会被监控 mock_conn = Mock() # 让连接对象的cursor()方法返回我们的桩化cursor mock_conn.cursor.return_value = mock_cursor # 2. 调用要测试的业务函数 db_utils.get_user_details(mock_conn, 456) # 3. 验证execute的调用情况 # 先检查是否被调用了恰好一次 mock_cursor.execute.assert_called_once() # 再检查传入的SQL和参数是否完全符合预期 expected_sql = "SELECT name, email FROM users WHERE id = %s" expected_params = (456,) mock_cursor.execute.assert_called_with(expected_sql, expected_params) if __name__ == '__main__': unittest.main()
关键知识点说明
Mock():创建一个“假”对象,它的所有属性和方法都是可追踪的,能记录被调用的次数、参数mock_conn.cursor.return_value = mock_cursor:告诉桩化的连接对象,当调用它的cursor()方法时,返回我们预先准备好的桩化cursorassert_called_once():验证execute方法被调用了刚好一次,避免重复执行或者漏执行assert_called_with():精确验证调用execute时传入的SQL语句和参数是否和预期完全一致
额外场景:如果业务代码内部创建连接
要是你的业务代码不是传入Connection,而是自己创建连接(比如conn = MySQLdb.connect(host='xxx')),那可以用patch来桩化连接类:
def test_get_user_with_internal_connection(self): # 用patch桩化业务代码里的MySQLdb.connect方法 with patch('db_utils.MySQLdb.connect') as mock_connect: # 配置桩化的连接和cursor mock_cursor = Mock() mock_conn = Mock() mock_connect.return_value = mock_conn mock_conn.cursor.return_value = mock_cursor # 调用业务函数(现在函数内部会创建桩化的连接) db_utils.get_user_details(456) # 验证execute的调用参数 mock_cursor.execute.assert_called_with( "SELECT name, email FROM users WHERE id = %s", (456,) )
内容的提问来源于stack exchange,提问作者bwrabbit
相关产品推荐
相关产品推荐

