Search code examples
pythonunit-testingmockingpytestpython-mock

How to mock objects methods return value


what I currently have is:

def some_method():
    some_obj = some_other_method()
    # This is what I want to mock return value of:
    some_obj.some_obj_some_method()

@patch('some_package.some_other_method')
def test_some_stuff(some_other_method_patch):
    some_other_method_patch.return_value = SomeObject()

How could I get about setting some_obj.some_obj_some_method() return value to False?


Solution

  • patch('some_package.some_other_method') will replace the function some_other_method with a Mock. Now you need to replace the return value of the method some_obj_some_method of this mock:

    mock.return_value.some_obj_some_method.return_value = False
    

    The complete example:

    # some_package.py
    
    class SomeObject:
        def some_obj_some_method(self):
            raise RuntimeError()
    
    
    def some_other_method():
        return SomeObject()
    
    
    def some_method():
        some_obj = some_other_method()
        # This is what you want to mock return value of:
        return some_obj.some_obj_some_method()
    

    Test:

    from unittest.mock import patch
    from some_package import SomeObject, some_method
    
    @patch('some_package.some_other_method')
    def test_some_stuff(function_mock):
        function_mock.return_value.some_obj_some_method.return_value = False
        assert not some_method()
    

    The test will pass as is, will raise a RuntimeError without patching and fail the assertion without the line function_mock.return_value.some_obj_some_method.return_value = False because some_method will only return a Mock that is never False.