Using python's mock patch.object to change the return value of a method called within another method Using python's mock patch.object to change the return value of a method called within another method python python

Using python's mock patch.object to change the return value of a method called within another method


There are two ways you can do this; with patch and with patch.object

Patch assumes that you are not directly importing the object but that it is being used by the object you are testing as in the following

#foo.pydef some_fn():    return 'some_fn'class Foo(object):    def method_1(self):        return some_fn()
#bar.pyimport fooclass Bar(object):    def method_2(self):        tmp = foo.Foo()        return tmp.method_1()
#test_case_1.pyimport barfrom mock import patch@patch('foo.some_fn')def test_bar(mock_some_fn):    mock_some_fn.return_value = 'test-val-1'    tmp = bar.Bar()    assert tmp.method_2() == 'test-val-1'    mock_some_fn.return_value = 'test-val-2'    assert tmp.method_2() == 'test-val-2'

If you are directly importing the module to be tested, you can use patch.object as follows:

#test_case_2.pyimport foofrom mock import patch@patch.object(foo, 'some_fn')def test_foo(test_some_fn):    test_some_fn.return_value = 'test-val-1'    tmp = foo.Foo()    assert tmp.method_1() == 'test-val-1'    test_some_fn.return_value = 'test-val-2'    assert tmp.method_1() == 'test-val-2'

In both cases some_fn will be 'un-mocked' after the test function is complete.

Edit:In order to mock multiple functions, just add more decorators to the function and add arguments to take in the extra parameters

@patch.object(foo, 'some_fn')@patch.object(foo, 'other_fn')def test_foo(test_other_fn, test_some_fn):    ...

Note that the closer the decorator is to the function definition, the earlier it is in the parameter list.


This can be done with something like this:

# foo.pyclass Foo:    def method_1():        results = uses_some_other_method()# testing.pyfrom mock import patch@patch('Foo.uses_some_other_method', return_value="specific_value"):def test_some_other_method(mock_some_other_method):    foo = Foo()    the_value = foo.method_1()    assert the_value == "specific_value"

Here's a source that you can read: Patching in the wrong place


Let me clarify what you're talking about: you want to test Foo in a testcase, which calls external method uses_some_other_method. Instead of calling the actual method, you want to mock the return value.

class Foo:    def method_1():       results = uses_some_other_method()    def method_n():       results = uses_some_other_method()

Suppose the above code is in foo.py and uses_some_other_method is defined in module bar.py. Here is the unittest:

import unittestimport mockfrom foo import Fooclass TestFoo(unittest.TestCase):    def setup(self):        self.foo = Foo()    @mock.patch('foo.uses_some_other_method')    def test_method_1(self, mock_method):        mock_method.return_value = 3        self.foo.method_1(*args, **kwargs)        mock_method.assert_called_with(*args, **kwargs)

If you want to change the return value every time you passed in different arguments, mock provides side_effect.