Pytest:解决assert_called_with因list.clear()引发的断言失败问题
问题原因
你遇到的问题核心是可变对象的引用传递:save_data方法中,self.db.save(self.my_data)传递的是self.my_data列表的引用,而非值的拷贝。后续执行self.my_data.clear()会直接修改这个列表对象,而mock的断言会检查该对象的当前状态,导致断言时看到的是空列表。
解决方案
下面提供几种可行的解决方式:
方式一:直接校验调用参数的实际值
通过call_args获取调用时传入的参数,比较其内容而非引用:
def test_save_data(main_module): input_data = sample(range(1, 100), 10) main_module.my_data = deepcopy(input_data) main_module.save_data() # 获取save方法调用时的第一个位置参数 called_data = main_module.db.save.call_args[0][0] assert called_data == input_data
方式二:在mock中捕获参数时保存副本
替换save方法,在调用时立即保存参数的副本,避免后续修改影响断言:
def test_save_data(main_module): input_data = sample(range(1, 100), 10) main_module.my_data = deepcopy(input_data) # 用自定义mock捕获参数副本 saved_data_list = [] def mock_save(data): saved_data_list.append(data.copy()) main_module.db.save = mock_save main_module.save_data() assert saved_data_list[0] == input_data
方式三:结合调用次数校验参数内容
如果想保留assert_called_*风格的断言,可以先验证调用次数,再检查参数值:
def test_save_data(main_module): input_data = sample(range(1, 100), 10) main_module.my_data = deepcopy(input_data) main_module.save_data() main_module.db.save.assert_called_once() assert main_module.db.save.call_args[0][0] == input_data
内容的提问来源于stack exchange,提问作者user7080013
相关产品推荐
相关产品推荐

