如何用pytest monkeypatch为链式调用API的嵌套execute函数打补丁
链式调用API的补丁实现方案
链式调用的本质是每一层方法调用后,都会返回包含下一层方法的实例,只需顺着调用路径模拟各层的返回对象,在最末层的execute方法返回需要的模拟值即可,无需复刻原API的完整内部逻辑。
方案1:自定义模拟类实现
适合需要定制各层方法逻辑的复杂场景,代码可读性更高:
# 模拟function_2调用后的返回实例,包含目标execute方法 class MockFunction2Return: def execute(self): # 直接返回测试需要的模拟响应 return {"code": 200, "data": "mock success"} # 模拟function_1调用后的返回实例,包含function_2方法 class MockFunction1Return: def function_2(self): return MockFunction2Return() # 测试用例中的补丁逻辑 def test_api_call(monkeypatch): # 模拟function_1的实现 def mock_function_1(*args, **kwargs): return MockFunction1Return() # 给目标类的function_1打补丁 monkeypatch.setattr(SomeAPIClass, "function_1", mock_function_1) # 调用原链式代码验证结果 res = SomeAPIClass.function_1().function_2().execute() assert res["data"] == "mock success"
方案2:基于Mock对象快速实现
适合简单场景,无需手动定义多层模拟类:
from unittest.mock import Mock def test_api_call(monkeypatch): # 模拟最末层execute方法的返回值 mock_execute = Mock(return_value={"code": 200, "data": "mock success"}) # 模拟function_2调用后的返回对象,绑定execute方法 mock_func2_return = Mock(execute=mock_execute) # 模拟function_2方法,返回上面的对象 mock_function_2 = Mock(return_value=mock_func2_return) # 模拟function_1调用后的返回对象,绑定function_2方法 mock_func1_return = Mock(function_2=mock_function_2) # 模拟function_1方法,返回上面的对象 mock_function_1 = Mock(return_value=mock_func1_return) # 打补丁 monkeypatch.setattr(SomeAPIClass, "function_1", mock_function_1) # 验证调用结果 res = SomeAPIClass.function_1().function_2().execute() assert res["data"] == "mock success"
如果需要校验function_1、function_2的入参,直接给对应模拟方法添加side_effect或者入参断言逻辑即可,按需调整即可满足测试需求。
内容的提问来源于stack exchange,提问作者zafar
相关产品推荐
相关产品推荐

