【问题标题】:How to mock a method on an object in a class?如何模拟类中对象的方法?
【发布时间】:2020-04-20 23:51:03
【问题描述】:

我正在尝试弄清楚如何使用额外的间接级别进行模拟 - 类中对象的方法。

import serial

class MyClass(object):

  def __init__(self, com_port, baudrate):
      self.sp = serial.Serial(com_port, baudrate)

  def do_something(self, data):
      num_bytes_written = self.sp.write(data)
      if num_bytes_written != len(data):
          return -1
      return 0

在测试文件中:

import mock

...

@mock.patch('serial.Serial', return_value='')
@mock.patch('serial.Serial.write', return_value=0)
def test_do_something_fails_on_bad_write(self, mock_write):
    ...
    want = -1
    dummy_data = b'123'
    inst = myfile.MyClass('COM8', 115200)
    got = c.do_something(dummy_data)
    self.assertEqual(got, want)

【问题讨论】:

    标签: python-2.7 mocking python-unittest python-mock


    【解决方案1】:

    单元测试解决方案:

    serial.py:

    class Serial(object):
        def __init__(self, port, baudrate):
            self.port = port
            self.baudrate = baudrate
    
        def write(self, data):
            return 100
    

    myclass.py:

    import serial
    
    
    class MyClass(object):
    
        def __init__(self, com_port, baudrate):
            self.sp = serial.Serial(com_port, baudrate)
    
        def do_something(self, data):
            num_bytes_written = self.sp.write(data)
            if num_bytes_written != len(data):
                return -1
            return 0
    

    test_myclass.py:

    import unittest
    from unittest import mock
    import serial
    import myclass
    
    
    class TestMyClass(unittest.TestCase):
        @mock.patch('myclass.serial.Serial')
        def test_do_something_fails_on_bad_write(self, mock_Serial):
            serial_instance = mock_Serial()
            serial_instance.write.return_value = 1
            want = -1
            dummy_data = b'123'
            c = myclass.MyClass('COM8', 115200)
            got = c.do_something(dummy_data)
            self.assertEqual(got, want)
            serial_instance.write.assert_called_once_with(b'123')
    
        @mock.patch('myclass.serial.Serial')
        def test_do_something_success(self, mock_Serial):
            serial_instance = mock_Serial()
            serial_instance.write.return_value = 3
            want = 0
            dummy_data = b'123'
            c = myclass.MyClass('COM8', 115200)
            got = c.do_something(dummy_data)
            self.assertEqual(got, want)
            serial_instance.write.assert_called_once_with(b'123')
    
    
    if __name__ == '__main__':
        unittest.main()
    

    带有覆盖率报告的单元测试结果:

    ..
    ----------------------------------------------------------------------
    Ran 2 tests in 0.002s
    
    OK
    Name                                         Stmts   Miss  Cover   Missing
    --------------------------------------------------------------------------
    src/stackoverflow/61333922/myclass.py            9      0   100%
    src/stackoverflow/61333922/serial.py             6      3    50%   3-4, 7
    src/stackoverflow/61333922/test_myclass.py      25      0   100%
    --------------------------------------------------------------------------
    TOTAL                                           40      3    92%
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多