简体   繁体   中英

Mocking member object methods in python

I want to mock the read and write functions of the Serial object from pyserial, which is used inside my class, to check for call arguments and edit the return values, but it doesn't seem to work.

Currently I have a file 'serialdevice.py', like this:

import serial

class SerialDevice:
    def __init__(self):
        self._serial = serial.Serial(port='someport')

    def readwrite(self, msg):
        self._serial.write(msg)
        return self._serial.read(1024)

Then I have a file 'test_serialdevice.py', like this:

import mock
from serialdevice import SerialDevice

@mock.patch('serialdevice.serial.Serial.read')
@mock.patch('serialdevice.serial.Serial.write')
@mock.patch('serialdevice.serial.Serial')
def test_write(mock_serial, mock_write, mock_read):
    mock_read.return_value='hello'
    sd = SerialDevice()
    resp = sd.readwrite('test')

    mock_write.assert_called_once_with('test')
    assert resp == 'hello'

But both asserts fail. Somehow the mock_write is not called with the argument 'test' and the write method returns a mock object instead of the 'hello' string. I've also tried using @patch('serial.Serial.write) etc. with the same results. Also using the return objects of mock_serial , so eg mock_read = mock_serial.read() does not seem to work.

The constructor, ie mock_serial , does seem to be called with the expected arguments however.

How can I achieve what I want in this case?

The python version is 2.7.9

Apparently you have to use the return value of the mock_serial object as the instance returned by the constructor, so something like

mock_serial.return_value.read.return_value = 'hello'

This works, but I still wonder if there is a better way to do this

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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