在单元测试中模拟python类并验证实例 [英] Mocking python class in unit test and verifying an instance

查看:118
本文介绍了在单元测试中模拟python类并验证实例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试对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类并验证实例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆