【发布时间】:2015-07-29 23:49:32
【问题描述】:
我正在处理一个项目,该项目涉及连接到远程服务器、等待响应,然后根据该响应执行操作。我们捕获了几个不同的异常,并且根据捕获的异常而表现出不同的行为。例如:
def myMethod(address, timeout=20):
try:
response = requests.head(address, timeout=timeout)
except requests.exceptions.Timeout:
# do something special
except requests.exceptions.ConnectionError:
# do something special
except requests.exceptions.HTTPError:
# do something special
else:
if response.status_code != requests.codes.ok:
# do something special
return successfulConnection.SUCCESS
为了测试这一点,我们编写了如下测试
class TestMyMethod(unittest.TestCase):
def test_good_connection(self):
config = {
'head.return_value': type('MockResponse', (), {'status_code': requests.codes.ok}),
'codes.ok': requests.codes.ok
}
with mock.patch('path.to.my.package.requests', **config):
self.assertEqual(
mypackage.myMethod('some_address',
mypackage.successfulConnection.SUCCESS
)
def test_bad_connection(self):
config = {
'head.side_effect': requests.exceptions.ConnectionError,
'requests.exceptions.ConnectionError': requests.exceptions.ConnectionError
}
with mock.patch('path.to.my.package.requests', **config):
self.assertEqual(
mypackage.myMethod('some_address',
mypackage.successfulConnection.FAILURE
)
如果我直接运行该函数,一切都会按预期进行。我什至通过将raise requests.exceptions.ConnectionError 添加到函数的try 子句来进行测试。但是当我运行单元测试时,我得到了
ERROR: test_bad_connection (test.test_file.TestMyMethod)
----------------------------------------------------------------
Traceback (most recent call last):
File "path/to/sourcefile", line ###, in myMethod
respone = requests.head(address, timeout=timeout)
File "path/to/unittest/mock", line 846, in __call__
return _mock_self.mock_call(*args, **kwargs)
File "path/to/unittest/mock", line 901, in _mock_call
raise effect
my.package.requests.exceptions.ConnectionError
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "Path/to/my/test", line ##, in test_bad_connection
mypackage.myMethod('some_address',
File "Path/to/package", line ##, in myMethod
except requests.exceptions.ConnectionError:
TypeError: catching classes that do not inherit from BaseException is not allowed
我试图将我正在修补的异常更改为 BaseException,但我得到了或多或少相同的错误。
我已经读过https://stackoverflow.com/a/18163759/3076272,所以我认为它一定是一个糟糕的__del__ 钩子,但我不确定在哪里可以找到它,或者我什至可以在此期间做什么。我对unittest.mock.patch() 也比较陌生,所以我很可能在那里也做错了什么。
这是一个 Fusion360 插件,因此它使用的是 Fusion 360 的 Python 3.3 打包版本——据我所知,它是一个普通版本(即它们不会自己推出),但我对此并不肯定。
【问题讨论】:
-
FWIW 我可以通过使用stackoverflow.com/a/28507806/3076272 来解决这个问题,但我想知道为什么会这样。
-
这里的
requests是您自己的模块,还是来自python-requests.org 的requests模块? -
来自 python-requests.org 的那个
标签: python exception-handling python-requests python-3.3 python-mock