我编写了一个装饰器,如果发生了严重错误,就用断点()停止我的程序。
def the_breakpoint_dec(func):
@functools.wraps(func):
async def my_wrapper(func):
retval=await func(*args,**kwargs)
return retval if retval else breakpoint()
return my_wrapper我正在进行单元测试,希望确保断点命中,而不实际触发它,因此我一直试图用@mock.patch装饰器修补断点(),但它不起作用。我尝试过的20多个断点的一些测试路径是
@mock.patch('pdb.breakpoint')
@mock.patch('builtins.breakpoint')
@mock.patch('builtins.pdb.breakpoint')
@mock.patch('my_module.breakpoint')
@mock.patch('my_module.builtins.breakpoint')
@mock.patch('sys.breakpointhook')
@mock.patch('my_module.sys.breakpointhook')
@mock.patch('my_decorator_module.sys.breakpointhook')
@mock.patch('my_decorator_module.sys.breakpoint')然后使测试函数def并传入模拟:
#testmodule.py
pytestmark=pytest.mark.asyncio
@mock.patch('just_another_path_to_breakpoint()_that_doesnt_work')
async def test_func_to_test(self, mock_breakpoint, some_other_mock):
mock_breakpoint.return_value=None
await decorated_func()
mock_breakpoint.assert_called() # never hit because pdb prompt opens in interpreter正在测试的模块
#moduleundertest.py
class bar:
@the_breakpoint_dec
async def decorated_func(self):
for i in range(3)
try:
return await something_likely_to_fail()
except:
pass最初,我想要修补的断点()是从上面提到的装饰器调用的。在几个小时的故障之后,我注释掉了装饰器,并将断点()直接移到了被测试的方法中。修补仍然失败。什么是正确的方式来修补这个内置的,如果必须做一些特殊的事情来修补它时,它在一个装饰,这是什么东西?
发布于 2020-05-30 18:18:03
要解决问题,请将您的项目升级到3.8!
我试着在3.8版复制你的场景,但做不到,修补工作对我很有帮助。但是,当尝试3.7及以下时,修补程序停止工作,我的程序将进入断点。我对此没有任何解释。
下面是我编写的一个完整的运行示例。它运行function_to_test,模拟成功然后失败(True/False)。正如assert所证明的那样,它只在失败的情况下调用breakpoint(),但是由于我们模拟的breakpoint() --至少在3.8中--测试完全退出。
from unittest import mock
import functools
import asyncio
def break_if_function_fails(func):
@functools.wraps(func)
async def my_wrapper(*args, **kwargs):
retval = await func(*args, **kwargs)
return retval if retval else breakpoint()
return my_wrapper
@break_if_function_fails
async def function_to_test(retval):
return retval
@mock.patch('builtins.breakpoint')
async def do_test(mock_breakpoint):
print('Entering test')
await function_to_test(True)
mock_breakpoint.assert_not_called()
await function_to_test(False)
mock_breakpoint.assert_called()
print('Exiting test')
asyncio.run(do_test())完全相同的代码没有完成,但在3.7中触发了断点。
如果你必须和3.7呆在一起,你仍然可以
@mock.patch('builtins.breakpoint')
async def do_test(mock_breakpoint):
backup_breakpoint = builtins.breakpoint
builtins.breakpoint = mock_breakpoint
...
builtins.breakpoint = backup_breakpoint但这显然是丑陋的。
https://stackoverflow.com/questions/61897718
复制相似问题