[英]Mocking python class in unit test and verifying an instance
I'm trying to unit test an SFTP helper class that makes some calls to the pysftp module. 我正在尝试对SFTP帮助程序类进行单元测试,该类对pysftp模块进行了一些调用。 I want to mock the actual network calls from pysftp so there are no side effects, and just make sure that the class is correctly calling the underlying SFTP methods with the correct paramaters. 我想模拟来自pysftp的实际网络调用,因此没有副作用,只需确保该类使用正确的参数正确调用了基础SFTP方法。
Here is a simple example of my code so far: 到目前为止,这是我的代码的一个简单示例:
import pysftp
import unittest
import mock
class SFTPHelper(object):
def __init__(self, host, username, password, files_dir):
self.host = host
self.username = username
self.password = password
self.files_dir = files_dir
def list_files(self):
with pysftp.Connection(
self.host,
username=self.username,
password=self.password) as sftp:
return sftp.listdir(self.files_dir)
class TestSFTPHelper(unittest.TestCase):
@mock.patch('pysftp.Connection')
def test_list_files(self, mock_connection):
sftp_helper = SFTPHelper('somehost', 'someuser', 'somepassword', '/some/files/dir')
sftp_helper.list_files()
# this assertion passes
mock_connection.assert_called_with(
'somehost', password='somepassword', username='someuser')
# this assertion does not pass
mock_connection.listdir.assert_called_with('/some/files/dir')
The assertion error: 断言错误:
AssertionError: Expected call: listdir('/some/files/dir')
Not called
I assume it doesn't work because I need to assert that the function was called on the instance, but how do I get the instances of pysftp.Connection that was used in my method? 我认为它不起作用,因为我需要断言该函数是在实例上调用的,但是如何获取在我的方法中使用的pysftp.Connection实例呢?
You could configure the mock to return a new mock object with __enter__
and __exit__
methods defined. 您可以配置模拟,以返回定义了__enter__
和__exit__
方法的新模拟对象。 For example: 例如:
@mock.patch.object(
target=pysftp,
attribute='Connection',
autospec=True,
return_value=mock.Mock(
spec=pysftp.Connection,
__enter__=lambda self: self,
__exit__=lambda *args: None
)
)
def test_list_files(self, mock_connection):
# (contents of test case)
In addition, you may want to use: 另外,您可能要使用:
mock_connection.return_value.listdir.assert_called_with('/some/files/dir')
instead of: 代替:
mock_connection.listdir.assert_called_with('/some/files/dir')
As a side note, you could also replace both uses of assert_called_with
in your example with assert_called_once_with
. 作为一个侧面说明,你也可以更换的两种用法assert_called_with
在你的榜样assert_called_once_with
。
The end result: 最终结果:
$ python -m unittest test_sftp_helper.TestSFTPHelper.test_list_files
.
----------------------------------------------------------------------
Ran 1 test in 0.017s
OK
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.