如何让MySQL Connector的MagicMock实例中fetchone()方法返回None?
正确Mock MySQL Connector并让fetchone()返回None的解决方案
核心思路
不需要同时patch mysql.connector.connect和mysql.connector.cursor,只需要patch connect,然后通过链式Mock逐步设置上下文管理器、连接实例、游标实例的返回值,就能既避免真实数据库连接,又让fetchone()返回None。
业务代码回顾
你的业务代码使用上下文管理器实现数据库操作:
def fetch_a_row(): # establishing the connection with mysql.connector.connect(user='root',password='password',host='127.0.0.1',database='mydb') as conn: # Creating a cursor object using the cursor() method cursor = conn.cursor() cursor.execute("SELECT * FROM mytable") # return the fetchone() output return cursor.fetchone()
正确的测试代码实现
使用unittest.mock的patch和MagicMock完成Mock设置:
from unittest.mock import patch, MagicMock # 替换成你的业务代码所在模块 from your_module import fetch_a_row def test_fetch_a_row_returns_none(): # Patch mysql.connector.connect,阻止真实连接 with patch('mysql.connector.connect') as mock_connect: # 1. 设置上下文管理器的返回值:即with语句中的conn实例 mock_conn = MagicMock() mock_connect.return_value.__enter__.return_value = mock_conn # 2. 设置conn.cursor()返回的游标实例 mock_cursor = MagicMock() mock_conn.cursor.return_value = mock_cursor # 3. 指定fetchone()返回None mock_cursor.fetchone.return_value = None # 调用业务函数 result = fetch_a_row() # 验证逻辑(可选但推荐) assert result is None # 确认connect被正确调用 mock_connect.assert_called_once_with( user='root', password='password', host='127.0.0.1', database='mydb' ) # 确认游标创建、执行语句、fetchone都被调用 mock_conn.cursor.assert_called_once() mock_cursor.execute.assert_called_once_with("SELECT * FROM mytable") mock_cursor.fetchone.assert_called_once()
问题原因分析
- 同时patch connect和cursor的问题:你单独patch的
cursor与conn.cursor()返回的游标实例不是同一个对象,导致设置的fetchone()返回值不生效,最终返回默认的MagicMock实例。 - 仅patch cursor的问题:
connect未被Mock,代码会尝试创建真实的数据库连接,导致连接失败。
内容的提问来源于stack exchange,提问作者JuanKB1024
相关产品推荐
相关产品推荐

