你能用mock_open来模拟串行连接吗?

Can you use mock_open to simulate serial connections?

各位早安,

我正尝试在 Python 中进行一些单元测试以确认我的代码是否正常工作,但我很难让 Mock 任何东西适合我的测试用例。我是 Python 单元测试的新手,所以到目前为止这是一个艰难的一周。

程序的总结是我正在尝试对我拿到手的商业显示器进行串行控制,我想我会利用它作为最终使用 Python 的机会而不是而不是仅仅依靠我知道的其他语言之一。我有 pyserial,但在我开始向电视发送大量命令之前,我想学习单元测试部分,这样我就可以编写我预期的输出和输入。

我试过使用名为 dummyserial 的库,但它似乎无法识别我发送的输出。我想我会尝试一下 mock_open,因为我已经看到它也像标准 IO 一样工作,但它也没有接听电话。涉及的代码示例:

def testSendCmd(self):
    powerCheck = '{0}{1:>4}\r'.format(SharpCodes['POWER'], SharpCodes['CHECK']).encode('utf-8')
    read_text = 'Stuff\r'
    mo = mock_open(read_data=read_text)
    mo.in_waiting = len(read_text)
    with patch('__main__.open', mo):
        with open('./serial', 'a+b') as com:
            tv = SharpTV(com=com, TVID=999, tvInput = 'DVI')
            tv.sendCmd(SharpCodes['POWER'], SharpCodes['CHECK'])
            com.write(b'some junk')
    print(mo.mock_calls)
    mo().write.assert_called_with('{0}{1:>4}\r'.format(SharpCodes['POWER'], SharpCodes['CHECK']).encode('utf-8'))

而在 SharpTV class 中,有问题的功能:

def sendCmd(self, type, msg):
    sent = self.com.write('{0}{1:>4}\r'.format(type,msg).encode('utf-8'))
    print('{0}{1:>4}\r'.format(type,msg).encode('utf-8'))

显然,我正在尝试控制夏普电视。我知道命令是正确的,这不是问题所在。问题只是测试。根据 mock_open 页面上的文档,调用 mo.mock_calls 应该 return 一些调用的数据,但我得到的只是一组空的 [],尽管明显错误的 com.write(b'some junk')mo().write.assert_called_with(...) 正在 returning 并出现断言错误,因为它没有检测到来自 sendCmd 的写入。真正困扰我的是,我可以在交互模式下执行 mock_open 部分的示例,并且它按预期工作。

我错过了什么,我只是不知道是什么。我需要帮助让 dummyserial 工作,或者 mock_open.

为了回答我问题的一部分,我了解了 dummyserial 的功能。以下现在有效:

def testSendCmd(self):
    powerCheck = '{0}{1:>4}\r'.format(SharpCodes['POWER'], SharpCodes['CHECK'])
    com = dummyserial.Serial(
            port='COM1',
            baudrate=9600,
            ds_responses={powerCheck : powerCheck}
            )
    tv = SharpTV(com=com, TVID=999, tvInput = 'DVI')
    tv.sendCmd(SharpCodes['POWER'], SharpCodes['CHECK'])
    self.assertEqual(tv.recv(), powerCheck)

之前我将字典值编码为 utf-8。 dummyserial 库解码你 write(...) 的任何内容,因此它是一个直接的字符串与字符串比较。它还会在返回时将您正在 read() 编码为 latin1 的任何内容。