不使用pytest等测试框架如何拦截函数调用实现mock修改目标方法行为
问题根因
- 导入拼写错误:测试文件第一行的
rom bravado.testing...应为from bravado.testing...,否则代码直接导入失败无法运行。 - 补丁未激活生效:你调用
mock.patch.object()仅创建了补丁实例,没有通过start()方法激活,也没有用with上下文管理器包裹测试执行逻辑,补丁从未替换目标方法,一直运行的是原始extract_and_verify_apiresult实现。 - 包装函数参数错误:
amended_func调用原方法返回时,第三个参数错误传入了类object,而非实际的参数apiresult,就算补丁生效也会触发类型报错。 - side_effect使用不符合场景:你需要完全替换原方法的实现,直接给
new参数传入包装后的函数即可,不需要使用side_effect。
修正后可直接运行的测试代码
# test_entry_object.py from bravado.testing.response_mocks import BravadoResponseMock import mock import entry_object, pretendapi def amend_extract_and_verify_apiresult(original_func): def amended_func(self, posix_time : int, apiresult : object) -> (bool, object): print(f"{posix_time} {apiresult[0]['ret_msg']}") # 修正参数传递错误,传入实际的apiresult而非object类 return original_func(self, posix_time, apiresult) return amended_func def test_time_injector(): mock_client = mock.Mock(name='mock SwaggerClient') mock_client.Api.ApiEndpoint.return_value = \ BravadoResponseMock(result=lambda : \ ({'ret_code': 0, 'ret_msg': 'OK', 'ext_code': '', 'ext_info': ''}, '<bravado.requests_client.RequestsResponseAdapter object at 0x0000028385176518>') ) # 使用with块激活补丁,执行完自动回滚,无需pytest环境支持 with mock.patch.object(pretendapi.PretendApi, 'extract_and_verify_apiresult', # 直接用new参数替换为包装后的函数 new=amend_extract_and_verify_apiresult( pretendapi.PretendApi.extract_and_verify_apiresult), autospec=True): entry_object.the_time_injector(10, mock_client) if __name__ == "__main__": test_time_injector()
如果不想用with块,也可以手动控制补丁生命周期:
patcher = mock.patch.object(pretendapi.PretendApi, 'extract_and_verify_apiresult', new=..., autospec=True) patcher.start() try: entry_object.the_time_injector(10, mock_client) finally: patcher.stop()
内容的提问来源于stack exchange,提问作者LeanMan
相关产品推荐
相关产品推荐

