pytest mocker测试间未重置Mock导致结果异常问题求助
pytest-mocker 上下文管理器patch后测试间数据污染问题解析
问题本质
你遇到的不是pytest-mocker或unittest.mock.patch的已知bug,也和导入无关,核心问题是两次测试复用了同一个被深拷贝后的对象实例。
上下文管理器确实会在单个测试结束后拆除补丁,但如果两次patch的return_value指向的是同一个对象,那么第一个测试中对该对象的修改会被第二个测试继承——因为列表、字典都是可变类型,深拷贝只做了一次,后续返回的都是这个已经被修改的实例。
错误示例(你可能的写法)
比如你的测试代码可能是这样的(全局复用了同一个mock数据实例):
import pytest from unittest.mock import patch, deepcopy from dummy_module import delete_d_key # 全局定义深拷贝数据,两个测试都用它 original_data = [{'a':1, 'd':4}, {'b':2, 'd':5}] mock_data = deepcopy(original_data) def test_A(): with patch('dummy_module.dummy_module_2.function_that_returns_list_of_dict', return_value=mock_data): delete_d_key() # 此时mock_data里的'd'键已经被删除 def test_B(): with patch('dummy_module.dummy_module_2.function_that_returns_list_of_dict', return_value=mock_data): result = delete_d_key() # 这里读到的mock_data已经是test_A修改后的版本
修正方案
要确保每个测试拿到的都是全新的深拷贝实例,有两种常用方式:
- 方式一:在每个测试内部生成深拷贝数据
import pytest from unittest.mock import patch, deepcopy from dummy_module import delete_d_key original_data = [{'a':1, 'd':4}, {'b':2, 'd':5}] def test_A(): # 每个测试重新生成深拷贝实例 mock_data = deepcopy(original_data) with patch('dummy_module.dummy_module_2.function_that_returns_list_of_dict', return_value=mock_data): delete_d_key() def test_B(): mock_data = deepcopy(original_data) with patch('dummy_module.dummy_module_2.function_that_returns_list_of_dict', return_value=mock_data): result = delete_d_key() # 此时拿到的是全新的未修改数据
- 方式二:用side_effect返回新实例
如果不想在每个测试里重复写深拷贝,可以用side_effect每次调用都返回新的深拷贝:
import pytest from unittest.mock import patch, deepcopy from dummy_module import delete_d_key original_data = [{'a':1, 'd':4}, {'b':2, 'd':5}] def test_A(): def get_new_data(): return deepcopy(original_data) with patch('dummy_module.dummy_module_2.function_that_returns_list_of_dict', side_effect=get_new_data): delete_d_key() def test_B(): def get_new_data(): return deepcopy(original_data) with patch('dummy_module.dummy_module_2.function_that_returns_list_of_dict', side_effect=get_new_data): result = delete_d_key()
总结
- 上下文管理器的patch拆除是正常工作的,问题出在可变对象实例的复用
- 解决的核心是确保每个测试用例获取到的mock返回值都是独立的新实例
- 这不属于框架bug,是可变类型在测试中常见的复用误区
内容的提问来源于stack exchange,提问作者azman
相关产品推荐
相关产品推荐

