Python 嘲笑 Netmiko

Python Mocking Netmiko

我正在为一个项目构建一个 netmiko 包装器,我正在尝试编写一些简单的单元测试来验证功能。但是我在模拟 netmiko 库时遇到了麻烦。我能够很容易地模拟 ConnectHandler 对象的创建,但是调用处理程序的验证方法没有按预期工作。

在下面的代码中,您将看到我的简单包装器和单元测试。问题在于test_disconnect。我正在尝试验证是否调用了 disconnect 方法,但由于某种原因,mock 报告它未被调用。我确定这与我嘲笑 netmiko 的方式有关,但我不确定我做错了什么。

MockSandbox.py

from netmiko import ConnectHandler, NetMikoTimeoutException


class SshLib(object):
    def __init__(self, ip, user, passwd, port=22):
        self.ip = ip
        self.user = user
        self.passwd = passwd
        self.port = port
        self.connection = None

    def login(self):
        args = {"device_type": "cisco_ios",
                "ip": self.ip,
                "username": self.user,
                "password": self.passwd,
                "port": self.port}

        try:
            self.connection = ConnectHandler(**args)
            return True
        except NetMikoTimeoutException:
            return False

    def disconnect(self):
        self.connection.disconnect()

MockSandboxTests.py

import mock
import unittest
from MockSandbox import SshLib


class SshLibTests(unittest.TestCase):
    @mock.patch("MockSandbox.ConnectHandler")
    def test_connect(self, mock_ssh):
        ssh = SshLib("1.1.1.1", "user", "password")
        return_val = ssh.login()

        args = {"device_type": "cisco_ios",
                "ip": "1.1.1.1",
                "username": "user",
                "password": "password",
                "port": 22}

        mock_ssh.assert_called_with(**args)
        self.assertTrue(return_val)

    @mock.patch("MockSandbox.ConnectHandler")
    def test_disconnect(self, mock_ssh):
        ssh = SshLib("1.1.1.1", "user", "password")
        ssh.login()
        ssh.disconnect()
        mock_ssh.disconnect.assert_called()


if __name__ == '__main__':
    unittest.main()

测试输出

Failure
Traceback (most recent call last):
  File "C:\Python27\lib\unittest\case.py", line 329, in run
    testMethod()
  File "C:\Python27\lib\site-packages\mock\mock.py", line 1305, in patched
    return func(*args, **keywargs)
  File "C:\Users\user\Python\MockSandboxTests.py", line 26, in test_disconnect
    mock_ssh.disconnect.assert_called()
  File "C:\Python27\lib\site-packages\mock\mock.py", line 906, in assert_called
    raise AssertionError(msg)
AssertionError: Expected 'disconnect' to have been called.



Ran 2 tests in 0.020s

FAILED (failures=1)

mock.patch("MockSandbox.ConnectHandler") returns 你是 class 的模仿者,所以 mock_ssh.disconnect 是一种 class 方法。你想改为检查实例方法。通过 mock_ssh.return_value:

访问模拟实例
mock_ssh.return_value.disconnect.assert_called()