如何在测试方法中模拟受保护/私有方法?

时间:2017-08-07 23:57:53

标签: python unit-testing python-unittest python-unittest.mock

我有一个包含2种方法的Python Clas。

第一个,_getTemperature_()受到保护,第二个是公共方法。我必须写一个unitTest,但我不知道如何模拟受保护的方法?我刚刚找到教程来模拟在测试直接使用的公共方法。但不是在一种可以测试的方法中。

class StateOn(self):

    #Temperature in °C
    _target = 15

    # currrent Temperature by Sensor in °C
    def _getTemperature_(self):
        return valueFromSensorXY()


    def validateTemperature(self):
        if self._getTemperature_() >= self._target:
            return StateOff()

有人可以给我一个暗示或解释来找到解决这个问题的方法吗?

3 个答案:

答案 0 :(得分:4)

聚会有点晚了,但这里有一个替代方法:

from unittest import mock

class MyClass():
    def __my_method(self):
        # Implement logic here...
        pass

def test_my_class():
    my_class = MyClass()
    my_class._MyClass__my_method = mock.Mock()
    # Run testing stuff...

通过将 my_class._MyClass__my_method 设置为 mock.Mock(),我们实际上有一个模拟来代替私有方法。

请注意,由于 Python 的私有属性 name mangling,我们需要设置 my_class._MyClass__my_method 而不是 my_class.__my_method

答案 1 :(得分:2)

fake_temp = 15
with mock.patch.object(StateOn, '_getTemperature', return_value=fake_temp) as mock_temp:
    result = StateOn().validateTemperature()
    self.assertIsInstance(result, StateOff)

答案 2 :(得分:0)

def test_validate_temprature(self):
   state = StateOn()
   fake_temp = 15
   with mock.patch.object(state, '_StateOn__getTemperature_', return_value=fake_temp) as temp_mock:
       result = state.validateTemperature()
       self.assertIsInstance(result, StateOff)
       temp_mock.assert_called_once()