I have recently started using the mock framework in python. It seems that if I patch a function, the actual code is not called - which means that the database changes etc that this actual function does is not implemented.
I have been trying to go around it by calling the function before hand and storing the return value and passing it as arg in patch(), but
is there a better way to do it? Ideally, I would want a code that works as a silent observer
and i can simply ask it if a certain observed
function was called or not, how many times, and with what arguments
return_val = funct()
# C: Now call me again and assert that these intensive computation functions are not called but taken from cache
with patch('funct', return_value=return_val) as mock_task:
me_response = self.client.get(me_url, format='json') #should fetch from cache
assert not mock_task.called
How do we mock in Python? Mocking in Python is done by using patch to hijack an API function or object creation call. When patch intercepts a call, it returns a MagicMock object by default. By setting properties on the MagicMock object, you can mock the API call to return any value you want or raise an Exception .
So what is the difference between them? MagicMock is a subclass of Mock . It contains all magic methods pre-created and ready to use (e.g. __str__ , __len__ , etc.). Therefore, you should use MagicMock when you need magic methods, and Mock if you don't need them.
side_effect: A function to be called whenever the Mock is called. See the side_effect attribute. Useful for raising exceptions or dynamically changing return values. The function is called with the same arguments as the mock, and unless it returns DEFAULT , the return value of this function is used as the return value.
To mock a method called, you should use the wraps
keyword. Consider the following:
class Foo(object):
def do_thing(self, a):
print("A: %s" % a)
self._do_private_thing(a)
def _do_private_thing(self, a):
print("PRIVATE STUFF HAPPENING.")
print("A: %s" % a)
Then In your test you would have something like:
import mock
a = Foo()
with mock.patch.object(a, '_do_private_thing', wraps=a._do_private_thing) as private_mock:
a.do_thing("lol")
private_mock.assert_called_with("lol")
Hope this helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With