2015-11-13 72 views
0

我想测试一个使用串行模块的串行类的类。 我知道我必须嘲笑他们,但我不明白这一点和运行:Python单元测试模拟并修补外部模块

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) 
  • 有关完整的TestClass:我如何嘲笑串口类,以便它不会使用真的吗?

  • 对于一些测试:我如何模拟带有参数x和返回值的Serial.read(x)? (就像Serial.inWaiting())

  • 对于一些测试:我如何嘲笑Serial.write(消息)参数,然后测试它用参数消息调用?

  • 一个额外的问题:我应该使用unittest2吗?

回答

0

也许最好的方式来做到这一点是patchSerial类。在你的情况,你在测试模块进口Serial,并修补它,你应该使用这样的

def setUp(self): 
    patcher = patch("__main__.Serial", autospec=True) 
    self.mock = patcher.start() 
    self.addCleanup(patcher.stop) 
    self.mc = MyClass() 
    self.mock.reset_mock() 

如果通过self.mocktest_read更改如下,以mock任何引用您的测试应该工作:

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)