我使用side_effect试图在调用模拟程序时引发异常,但遇到一个我不理解的DID NOT RAISE EXCEPTION
错误。
在很大程度上基于此answer,我创建了一个简单的示例,其中有一个Query
类和一个类方法make_request_and_get_response
,该类方法可能引发多个异常。这些异常正在get_response_from_external_api
的{{1}}方法中处理。
query.py
main.py
main.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.URLError as e:
print('Got a URLError: ', e)
except urllib.error.HTTPError as e:
print('Got a HTTPError: ', e)
# {{various other exceptions}}
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
时使用,期望此最后一次调用会产生'URLError'异常。
test_main.py
make_request_and_get_response
上面的测试给出以下错误:
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'
答案 0 :(得分:1)
Pytest无法检测到异常,因为您在get_response_from_external_api
中正在捕获所有异常。根据您的要求,您可以选择以下选项:
get_response_from_external_api
中捕获异常。pytest.raises
的异常。