Python3:如何测试with内的异常?
Python 3: how to tests exceptions within with?
我在测试 python 3.4 中的 with 中引发的异常时遇到问题。我只是无法获得这段代码的测试 运行:
import logging
...
class Foo(object):
...
def foo(self, src, dst):
try:
with pysftp.Connection(self._host, username=self._username, password=self._password) as connection:
connection.put(src, dst)
connection.close()
except (
ConnectionException,
CredentialException,
SSHException,
AuthenticationException,
HostKeysException,
PasswordRequiredException
) as e:
self._log.error(e)
这就是我想要测试的方式:
import logging
...
class TestFoo(TestCase):
@parameterized.expand([
('ConnectionException', ConnectionException),
('CredentialException', CredentialException),
('SSHException', SSHException),
('AuthenticationException', AuthenticationException),
('HostKeysException', HostKeysException),
('PasswordRequiredException', PasswordRequiredException),
])
@patch('pysftp.Connection', spec_set=pysftp.Connection)
def test_foo_exceptions(self, _, ex, sftp_mock):
"""
NOTE: take a look at:
to get an understanding of __enter__ and __exit__
"""
sftp_mock.return_value = Mock(
spec=pysftp.Connection,
side_effect=ex,
__enter__ = lambda self: self,
__exit__ = lambda *args: None
)
foo = Foo('host', 'user', 'pass', Mock(spec_set=logging.Logger))
foo.foo('src', 'dst')
self.assertEqual(foo._log.error.call_count, 1)
但它失败了 - 输出:
Failure
...
AssertionError: 0 != 1
你的 sftp_mock.return_value
对象永远不会被调用,所以 side_effect
永远不会被触发,也不会引发异常。只有当 pysftp.Connection(...)
的 return 值 本身被再次调用时才会被调用。
直接在 mock 上设置副作用 :
sftp_mock.side_effect = ex
请注意,现在 pysftp.Connection(...)
表达式引发了异常,并且该表达式的 return 值已被用作 with
语句中的上下文管理器不再重要.
注意你的异常会抱怨没有得到任何参数;传入异常的 个实例 ,而不是类型:
@parameterized.expand([
('ConnectionException', ConnectionException('host', 1234)),
# ... etc.
])
我在测试 python 3.4 中的 with 中引发的异常时遇到问题。我只是无法获得这段代码的测试 运行:
import logging
...
class Foo(object):
...
def foo(self, src, dst):
try:
with pysftp.Connection(self._host, username=self._username, password=self._password) as connection:
connection.put(src, dst)
connection.close()
except (
ConnectionException,
CredentialException,
SSHException,
AuthenticationException,
HostKeysException,
PasswordRequiredException
) as e:
self._log.error(e)
这就是我想要测试的方式:
import logging
...
class TestFoo(TestCase):
@parameterized.expand([
('ConnectionException', ConnectionException),
('CredentialException', CredentialException),
('SSHException', SSHException),
('AuthenticationException', AuthenticationException),
('HostKeysException', HostKeysException),
('PasswordRequiredException', PasswordRequiredException),
])
@patch('pysftp.Connection', spec_set=pysftp.Connection)
def test_foo_exceptions(self, _, ex, sftp_mock):
"""
NOTE: take a look at:
to get an understanding of __enter__ and __exit__
"""
sftp_mock.return_value = Mock(
spec=pysftp.Connection,
side_effect=ex,
__enter__ = lambda self: self,
__exit__ = lambda *args: None
)
foo = Foo('host', 'user', 'pass', Mock(spec_set=logging.Logger))
foo.foo('src', 'dst')
self.assertEqual(foo._log.error.call_count, 1)
但它失败了 - 输出:
Failure
...
AssertionError: 0 != 1
你的 sftp_mock.return_value
对象永远不会被调用,所以 side_effect
永远不会被触发,也不会引发异常。只有当 pysftp.Connection(...)
的 return 值 本身被再次调用时才会被调用。
直接在 mock 上设置副作用 :
sftp_mock.side_effect = ex
请注意,现在 pysftp.Connection(...)
表达式引发了异常,并且该表达式的 return 值已被用作 with
语句中的上下文管理器不再重要.
注意你的异常会抱怨没有得到任何参数;传入异常的 个实例 ,而不是类型:
@parameterized.expand([
('ConnectionException', ConnectionException('host', 1234)),
# ... etc.
])