如何为pymssql编写pytest用例并Mock数据库连接解决断言错误
问题原因
你的代码存在4个核心错误导致报错:
fetchall返回值多套了一层MagicMock:你给mock_cursor.fetchall.return_value又赋值了一个MagicMock对象,导致调用cursor.fetchall()返回的是Mock实例而非你预设的test_data- 上下文管理器的Mock链路写错:
pymssql.connect使用了with语法,connect.return_value的__enter__返回值才是赋值给conn的连接对象,你直接跳过了__enter__这一层 - 调用
cur_fetch时入参错误:方法要求传入字符串类型的SQL语句,你传入了字典{},不符合入参要求 - 断言逻辑错误:你预期方法返回None,但正常逻辑应该返回你模拟的
test_data
修正后的测试代码
# test_fetch.py from unittest.mock import MagicMock, patch from fetch import cur_fetch def test_cur_fetch(): test_query = "SELECT * FROM test_table" test_data = [{'password': 'secret', 'id': 1}] with patch('fetch.pymssql', autospec=True) as mock_pymssql: # 构造模拟游标 mock_cursor = MagicMock() mock_cursor.fetchall.return_value = test_data # 匹配业务代码的上下文调用链路:connect() -> __enter__() -> 连接对象 -> cursor() -> __enter__() -> 游标对象 mock_conn = MagicMock() mock_conn.cursor.return_value.__enter__.return_value = mock_cursor mock_pymssql.connect.return_value.__enter__.return_value = mock_conn result = cur_fetch(test_query) # 校验返回结果 assert result == test_data # 可选:校验调用参数符合预期 mock_pymssql.connect.assert_called_once_with('host', 'username', 'password') mock_conn.cursor.assert_called_once_with(as_dict=True) mock_cursor.execute.assert_called_once_with(test_query) mock_cursor.fetchall.assert_called_once()
验证说明
修正后的代码Mock链路完全匹配业务代码的执行逻辑,不需要连接真实数据库即可完成测试,不会再出现MagicMock比对错误。
内容的提问来源于stack exchange,提问作者XYZ
相关产品推荐
相关产品推荐

