Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to mock a protected/private method in a tested method?

I have a Python Clas with 2 methods.

The first, _getTemperature_() is protected and the second one is a public method. I have to write a unitTest but I have no clue, how to mock the protected method? I just found tutorials to mock a public method which is used at the test direct. But not in a method which sould be tested.

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()

Does someone can give me a hint, or an explaination to find a solution about this issue?

like image 298
michael-mammut Avatar asked Aug 07 '17 23:08

michael-mammut


2 Answers

A bit late to the party, but here's an alternative method:

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...

By setting my_class._MyClass__my_method to mock.Mock() we effectively have a mock in place of the private method.

Note that we need to set my_class._MyClass__my_method and not my_class.__my_method, due to Python's name mangling of private attributes.

like image 100
Renato Byrro Avatar answered Nov 03 '22 00:11

Renato Byrro


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()
like image 34
Chandan Kumar Avatar answered Nov 02 '22 23:11

Chandan Kumar