繁体   English   中英

使用模拟和修补外部模块的Python单元测试

[英]Python Unit testing with mock and patch a foreign modul

我想测试一个使用来自串行模块的Serial类的类。 我知道我必须模拟它们,但是我没有启动它并运行它:

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)
  • 对于完整的TestClass:我如何模拟Serial类,以便它不使用真正的类?

  • 对于某些测试:如何使用参数x模拟Serial.read(x)并返回值? (就像Serial.inWaiting()一样)

  • 对于某些测试:如何模拟带有参数的Serial.write(message),然后测试其是否带有参数message进行调用?

  • 一个奖励问题:我应该使用unittest2吗?

也许最好的方法是patch Serial类。 在您的情况下,您在测试模块中导入了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的任何引用更改为以下self.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)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM