使用side_effect,我试图在'URLError'
调用模拟时引发异常,但我收到一个DID NOT RAISE
我不理解的错误。
我有一个Query
带有类方法的类,make_request_and_get_response
它可以引发几个异常。我没有在 in 的方法中捕获'URLError'
异常,所以我应该能够期望被引发,然后,它的异常被嘲笑。get_response_from_external_api
main.py
查询.py
from urllib.request import urlopen
import contextlib
import urllib
class Query:
def __init__(self, a, b):
self.a = a
self.b = b
self.query = self.make_query()
def make_query(self):
# create query request using self.a and self.b
return query
def make_request_and_get_response(self): # <--- the 'dangerous' method that can raise exceptions
with contextlib.closing(urlopen(self.query)) as response:
return response.read().decode('utf-8')
主文件
from foo.query import *
def get_response_from_external_api(query):
try:
response = query.make_request_and_get_response()
except urllib.error.HTTPError as e:
print('Got a HTTPError: ', e)
except Exception:
print('Got a generic Exception!')
# handle this exception
if __name__ == "__main__":
query = Query('input A', 'input B')
result = get_response_from_external_api(query)
return result
使用pytest
,我试图模拟那个“危险”的方法 ( make_request_and_get_response
),它对特定的异常有副作用。然后,我继续创建一个模拟Query
对象以在调用时使用,make_request_and_get_response
并期望最后一次调用会给出“URLError”异常。
test_main.py
import pytest
from unittest.mock import patch
from foo.query import Query
from foo.main import get_response_from_external_api
class TestExternalApiCall:
@patch('foo.query.Query')
def test_url_error(self, mockedQuery):
with patch('foo.query.Query.make_request_and_get_response', side_effect=Exception('URLError')):
with pytest.raises(Exception) as excinfo:
q= mockedQuery()
foo.main.get_response_from_external_api(q)
assert excinfo.value = 'URLError'
# assert excinfo.value.message == 'URLError' # this gives object has no attribute 'message'
上面的测试给出了以下错误:
> foo.main.get_response_from_external_api(q)
E Failed: DID NOT RAISE <class 'Exception'> id='72517784'>") == 'URLError'
即使我捕获'URLError'
异常然后在get_response_from_external_api
.
有人可以帮助我了解我缺少什么以便能够在 pytest 中引发异常吗?
根据@SimeonVisser 的回复更新:
如果我修改main.py
以删除except Excpetion
案例:
def get_response_from_external_api(query):
try:
response = query.make_request_and_get_response()
except urllib.error.URLError as e:
print('Got a URLError: ', e)
except urllib.error.HTTPError as e:
print('Got a HTTPError: ', e)
然后测试test_main.py
:
def test_url_error2(self):
mock_query = Mock()
mock_query.make_request_and_get_response.side_effect = Exception('URLError')
with pytest.raises(Exception) as excinfo:
get_response_from_external_api(mock_query)
assert str(excinfo.value) == 'URLError'
测试通过 OK。