问题描述
我正在尝试对SFTP帮助程序类进行单元测试,该类对pysftp模块进行了一些调用.我想模拟来自pysftp的实际网络调用,因此没有副作用,只需确保该类正确地使用正确的参数来调用基础SFTP方法.
I'm trying to unit test an SFTP helper class that makes some calls to the pysftp module. 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.
这是到目前为止我的代码的一个简单示例:
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')
断言错误:
AssertionError: Expected call: listdir('/some/files/dir')
Not called
我认为它不起作用,因为我需要断言该函数是在实例上调用的,但是如何获取在我的方法中使用的pysftp.Connection实例呢?
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?
推荐答案
您可以配置模拟,以返回定义了__enter__
和__exit__
方法的新模拟对象.例如:
You could configure the mock to return a new mock object with __enter__
and __exit__
methods defined. 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')
代替:
mock_connection.listdir.assert_called_with('/some/files/dir')
请注意,您还可以在示例中将assert_called_with
的两种用法都替换为assert_called_once_with
.
As a side note, you could also replace both uses of assert_called_with
in your example with assert_called_once_with
.
最终结果:
$ python -m unittest test_sftp_helper.TestSFTPHelper.test_list_files
.
----------------------------------------------------------------------
Ran 1 test in 0.017s
OK
这篇关于在单元测试中模拟python类并验证实例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!