我正在使用 unittest 框架为 python 程序编写单元测试。该程序的功能之一是使用请求库连接到外部 REST API。如果出现连接错误或超时,我希望该功能在失败之前最多重试 3 次。因此,我编写了一个测试,它使用模拟(实际上是httpretty)来替换外部 API,并在返回某些内容之前引发 requests.ConnectionError 两次。
class APITests(unittest.TestCase):
def mock_response(self, uri, body='OK', method=httpretty.GET,
status_code=200, error=None,
error_repeats=None):
"""
Function to register HTTPretty response
"""
responses = []
if error:
def callback(request, uri, headers):
raise error
if error_repeats:
responses += [httpretty.Response(body=callback)]*error_repeats
responses += [httpretty.Response(body=body,
status=status_code)]
else:
responses += [httpretty.Response(body=callback)]
else:
responses += [httpretty.Response(body=body, status=status_code)]
httpretty.register_uri(method, uri, responses=responses)
@httpretty.activate
def test_get_connection_error_then_success_doesnt_raise(self):
self.mock_response(
'http://irrelevant.com',
error=requests.ConnectionError,
error_repeats=2
)
api._get('http://irrelevant.com')
这可以正常工作,并且当没有第三次尝试引发异常时测试通过,但是引发(有意)并由代码捕获和处理的两个异常被打印到控制台,从而污染了测试输出。有没有一种干净的方法来阻止这种情况发生?
更多信息
这是我正在测试的方法
def _get(self, url, retries=3):
while retries > 0:
try:
r = requests.get(url)
try:
r.raise_for_status()
return r
except requests.HTTPError as e:
self._handle_HTTP_error(e)
except (requests.ConnectionError, requests.Timeout) as e:
retries -= 1
if not retries:
self._handle_connection_error(e)
def _handle_connection_error(self, error):
raise requests.ConnectionError('Could not connect to API')
控制台输出为:
Exception in thread Thread-23:
Traceback (most recent call last):
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.py", line 810, in __bootstrap_inner
self.run()
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.py", line 763, in run
self.__target(*self.__args, **self.__kwargs)
File "/Users/lukecaldwell/Documents/Repos/other/AidTrends/venv/lib/python2.7/site-packages/httpretty/core.py", line 637, in fill_filekind
headers
File "/Users/lukecaldwell/Documents/Repos/other/AidTrends/aidtrends/tests/test_OECD.py", line 131, in callback
raise error
ConnectionError