Python 从pyserial继承时的模拟

Python 从pyserial继承时的模拟,python,unit-testing,mocking,pytest,Python,Unit Testing,Mocking,Pytest,我有一个从pyserial的serial.serial类继承的类,它看起来像这样: class SYM1(serial.Serial): def __init__(self, *args, debug=None, baudrate=4800, timeout=1, **kwargs): super().__init__(*args, baudrate=baudrate, timeout=timeout, **kwargs) LOG.info('using

我有一个从
pyserial
serial.serial
类继承的类,它看起来像这样:

class SYM1(serial.Serial):
    def __init__(self, *args, debug=None, baudrate=4800, timeout=1, **kwargs):
        super().__init__(*args, baudrate=baudrate, timeout=timeout, **kwargs)
        LOG.info('using port %s', self.port)

    def read(self, count):
        ...
        return super().read(count)

    def write(self, data):
        ...
        return super().write(data)

    def connect(self):
        ...

    def send_command(self, cmd, *args):
        ...
我想为类编写单元测试,但我不确定如何最好地进行设置,以便(a)在
SYM1
类上定义的方法可以正常调用,而(b)从
serial.serial
继承的方法可以模拟

我从这个开始:

import pytest
import serial

from unittest import mock


serial.Serial = mock.MagicMock
from symtool import symtool  # NOQA


@pytest.fixture
def sym(monkeypatch):
    s = symtool.SYM1('TESTDEV')
    s.connect()
    return s


def test_connect(sym):
    pass
但这在这里失败了:

LOG.info('using port %s', self.port)
与:

这让我很困惑,因为如果它是
mock.mock
对象,我希望:

>>> from unittest import mock
>>> m = mock.Mock()
>>> m.port
<Mock name='mock.port' id='139910315631568'>

这里发生了什么,正确的方法是什么?

考虑不使用继承,而是使用组合
SYM1.\uuuu init\uuuuu
将在生产环境中使用
Serial
的实例,但在测试中使用某个虚拟类的实例。您所有的
SYM1
方法都将使用该对象,而不是重写继承的方法。问题是我正在重写
read
write
方法,这些方法由
Serial
类的其他方法调用。我认为没有一种优雅的方式可以通过合成来实现这一点。
def read(self,count):返回self.serial\u obj.read(count)
。调用方不知道您是否正在使用
super
或委托给另一个对象。不,问题是当
serial.serial
中的方法调用例如
read
时。因此
SYM1
调用
self.read_直到(…)
,而
read_直到
方法(定义在
serial.serial
而不是
SYM1
上)调用
self.read
。如果我们调用
self.serial\u obj.read\u直到
,这将不起作用。
>>> from unittest import mock
>>> m = mock.Mock()
>>> m.port
<Mock name='mock.port' id='139910315631568'>
AttributeError: 'super' object has no attribute 'write'