def f1(): return 10, True def f2(): num, stat = f1() return 2*num, stat
How do I use python's mock library to patch f1()
and return a custom result so I could test f2()
?
Edited: Is there something wrong with my test? This doesn't seem to be working, all the tests failed with AssertionError
from foo.bar import f2 from mock import patch class MyTest(TestCase): def test_f2_1(self): with patch('project.module.f1') as some_func: some_func.return_value = (20, False) num, stat = f2() self.assertEqual((num, stat), (40, False)) @patch('project.module.f1') def test_f2_2(self, some_func): some_func.return_value = (20, False) num, stat = f2() self.assertEqual((num, stat), (40, False))
There are two ways to mock functions: Either by creating a mock function to use in test code, or writing a manual mock to override a module dependency.
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 .
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.
This, along with its subclasses, will meet most Python mocking needs that you will face in your tests. The library also provides a function, called patch() , which replaces the real objects in your code with Mock instances.
First example suggests that f1() and f2() defined in the same module. Hence the following should work:
from foo.bar import f2 from mock import patch class MyTest(TestCase): @patch('foo.bar.f1') def test_f2_2(self, some_func): some_func.return_value = (20, False) num, stat = f2() self.assertEqual((num, stat), (40, False))
Patch is on the same as import: @patch('foo.bar.f1')
Here is a good answer on the issue:
http://bhfsteve.blogspot.nl/2012/06/patching-tip-using-mocks-in-python-unit.html
Assuming that you're using this mock libary:
def f1(): return 10, True def f2(): num, stat = f1() return 2*num, stat import mock print f2() # Unchanged f1 -> prints (20, True) with mock.patch('__main__.f1') as MockClass: # replace f1 with MockClass MockClass.return_value = (30, True) # Change the return value print f2() # f2 with changed f1 -> prints (60, True)
If your code is divided into modules you would probably need to replace __main__.f1
with the path to your module/function.
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