我是Python的新手。我正在尝试在单元测试中模拟异常并测试我的代码块;但是,异常消息始终为空。下面是模拟异常的推荐方法吗?另外,如何确保异常消息不为空?
import pytest
import requests
from unittest.mock import patch
#Unit Test
@patch('requests.get')
def test_exception(mock_run):
mock_run.side_effect = requests.exceptions.ConnectionError()
with pytest.raises(SystemExit) as sys_exit:
method_to_test()
assert 'Error ' in str(sys_exit.value) # Here sys_exit.value is always empty
#Method to Test
def method_to_test():
try:
response = requests.get('some_url', verify=False, stream=True)
response.raise_for_status()
except (requests.exceptions.HTTPError,
requests.exceptions.ConnectionError,
requests.exceptions.Timeout) as err:
msg = f'Failure: {err}' # Here err is always empty
raise SystemExit(msg)
答案 0 :(得分:1)
如果要模拟异常,请在raise
块中try
进行异常,就像在except
块中引发异常一样。执行此操作时,可以将字符串参数传递为异常消息-
raise requests.exceptions.HTTPError("Test this error")
这会将消息过滤到except
块。
以您的示例为例:
def method_to_test():
try:
# ADD EXCEPTION HERE
raise requests.exceptions.HTTPError('Throwing an exception here!')
response = requests.get('some_url', verify=False, stream=True)
response.raise_for_status()
except (requests.exceptions.HTTPError,
requests.exceptions.ConnectionError,
requests.exceptions.Timeout) as err:
# err will now be 'Throwing an exception here!'
msg = f'Failure: {err}' # Here err is always empty
raise SystemExit(msg)
答案 1 :(得分:1)
长话短说:您没有收到消息,因为您未指定消息。
您可能要检查'Failure: '
而不是'Error: '
,因为这是给原始异常消息加上前缀的位置。这可能是代码中的真正问题,而不是测试中引发的异常的空字符串表示形式。
str(err)
为空?看看类的层次结构:
BaseException
Exception
IOError
requests.RequestException
requests.ConnectionError
IOError
将覆盖__str__
,如果为构造函数指定了多个参数,则BaseException
的行为适用:
如果在此类的实例上调用str(),则返回该实例的自变量的表示形式;如果没有自变量,则返回空字符串。 https://docs.python.org/3/library/exceptions.html#BaseException
>>> import requests
>>> str(requests.exceptions.ConnectionError())
''
>>> str(requests.exceptions.ConnectionError('foo'))
'foo'
>>> str(requests.exceptions.ConnectionError('foo', 'bar'))
'[Errno foo] bar'
最后一个示例是IOError
异常所定义的行为。