Python 使用 mock 和 patch 外部模块进行单元测试

Python Unit testing with mock and patch a foreign modul

我想测试一个 class,它使用来自串行模块的串行 class。 我知道我必须嘲笑他们,但我不明白 运行:

from serial import Serial

import unittest
from mock import patch, MagicMock

class MyClass(object):
    def __init__(self):
        self.ser = Serial('/dev', 123)

    def write(self, message):
        if self.ser:
            self.ser.write(message)
            return True

    def read(self):
        if self.ser.inWaiting():
            return self.ser.read(1)
        return None


class MyClassTest(unittest.TestCase):

    def setUp(self):

        self.mc = MyClass()

    def test_init(self):
        self.mc = MyClass()

        #Check if...
        mock.assert_called_with('/dev', 123)

    def test_write(self):
        self.mc.write('lala')

        #Check if...
        mock.write.assert_called_with('lala')

    def test_read(self):

        #patch inWaiting function...
        mock.inWaiting.retval = 4

        #patch inWaiting function...
        mock.read.retval = 'lulu'

        x = self.mc.read()

        self.assertEqual('lulu')

        #Check if...
        mock.read.assert_called_with(1)

也许最好的方法是 patch Serial class。在您的情况下,您在测试模块中导入了 Serial 并对其进行了修补,您应该使用类似这样的东西

def setUp(self):
    patcher = patch("__main__.Serial", autospec=True)
    self.mock = patcher.start()
    self.addCleanup(patcher.stop)
    self.mc = MyClass()
    self.mock.reset_mock()

如果您通过 self.mocktest_read 更改对 mock 的任何引用,则您的测试应该有效,如下所示:

def test_read(self):
    self.mock.inWaiting.return_value = 4
    self.mock.read.return_value = 'lulu'
    self.assertEqual(self.mc.read(), 'lulu')
    self.mock.read.assert_called_with(1)