简体   繁体   中英

Python Unit testing with mock and patch a foreign modul

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)

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