I would like to test a class which uses the Serial class from serial modul. I know i have to mock them, but i don't get it up and running:
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)
For the complete TestClass: How do i mock the Serial class so that it won't use the real one?
For some tests: How do i mock the Serial.read(x) with parameter x and return value? (just like Serial.inWaiting())
For some tests: How do i mock the Serial.write(message) with parameter and then test it for calling with parameter message?
One bonus question: should i use unittest2 ?
Maybe the best way to do it is to patch
Serial
class. In your case you imported Serial
in test module and to patch it you should use something like this
def setUp(self):
patcher = patch("__main__.Serial", autospec=True)
self.mock = patcher.start()
self.addCleanup(patcher.stop)
self.mc = MyClass()
self.mock.reset_mock()
Your test should work if you change any reference to mock
by self.mock
and test_read
as follow :
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)