如何使用@patch.object装饰器测试类中多次调用的方法?
解决多次调用Mock方法返回不同值的问题
针对你遇到的save方法被多次调用且需要返回不同文件URL的测试需求,可以通过unittest.mock的side_effect参数实现,具体有两种常用方式:
1. 按调用顺序返回固定值
直接给side_effect传入一个列表,Mock方法会按调用顺序依次返回列表中的元素。
示例代码:
import unittest from unittest.mock import patch from your_module import FileStoreSp, YourBusinessClass # 替换为实际模块和类 class TestBusinessClass(unittest.TestCase): # 按调用顺序返回两个不同的文件URL @patch.object(FileStoreSp, "save", side_effect=["https://test.com/file1.png", "https://test.com/file2.docx"]) def test_multiple_save_calls(self, mock_save): # 初始化被测业务类 business_obj = YourBusinessClass() # 触发会调用两次save的业务方法 business_obj.handle_multiple_files() # 验证save方法的调用次数 self.assertEqual(mock_save.call_count, 2) # 验证每次调用的参数是否符合预期(按需添加) mock_save.assert_has_calls( [ unittest.mock.call("file1_data"), # 第一次调用的参数 unittest.mock.call("file2_data") # 第二次调用的参数 ], any_order=False # 严格按顺序匹配 )
2. 根据传入参数动态返回值
如果需要根据save方法的入参返回对应URL,可以给side_effect传入一个自定义函数,函数接收调用时的参数,返回对应的结果。
示例代码:
def mock_save_logic(file_param): # 根据传入的文件参数返回不同URL if file_param == "avatar_data": return "https://test.com/user_avatar.png" elif file_param == "report_data": return "https://test.com/monthly_report.xlsx" else: return "https://test.com/default.file" class TestBusinessClass(unittest.TestCase): @patch.object(FileStoreSp, "save", side_effect=mock_save_logic) def test_dynamic_save_returns(self, mock_save): business_obj = YourBusinessClass() business_obj.handle_different_files() # 验证特定参数的调用返回值 self.assertEqual(mock_save.call_args_list[0].return_value, "https://test.com/user_avatar.png")
关键说明
side_effect不仅支持列表和函数,还可以抛出异常(用于测试错误场景)。- 测试时除了验证返回值,务必检查Mock方法的调用次数、入参是否符合业务逻辑,确保被测代码的行为正确。
内容的提问来源于stack exchange,提问作者Kulasangar
相关产品推荐
相关产品推荐

