I am trying to write unit tests for Bar
that makes calls to Foo
's method read()
. I have added the patch command in setUp()
because other tests will use this patch as well.
How can I check that the read()
function was called with the arguments that I am expecting?
foo.py
class Foo(object):
def __init__(self):
self.table = {'foo': 1}
def read(self, name):
return self.table[name]
bar.py
import foo
class Bar(object):
def act(self):
a = foo.Foo()
return a.read('foo')
test_bar.py
import bar
import unittest
from mock import patch
class TestBar(unittest.TestCase):
def setUp(self):
self.foo_mock = patch('bar.foo.Foo', autospec=True).start()
self.addCleanup(patch.stopall)
def test_can_call_foo_with_correct_arguments(self):
a = bar.Bar()
a.act()
self.foo_mock.read.assert_called_once_with('foo')
python -m unittest discover
F
======================================================================
FAIL: test_can_call_foo_with_correct_arguments (test_bar.TestBar)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/test_dir/test_bar.py", line 12, in test_can_call_foo_with_correct_arguments
self.foo_mock.read.assert_called_once_with('foo')
File "/usr/local/lib/python2.7/dist-packages/mock.py", line 845, in assert_called_once_with
raise AssertionError(msg)
AssertionError: Expected to be called once. Called 0 times.
----------------------------------------------------------------------
Ran 1 test in 0.001s
FAILED (failures=1)
Instead of using mock(class) here we need to use Mockito. spy() to mock the same class we are testing. Then we can mock the method we want as follows. Mockito.
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.
patch() as a Decorator If you want to mock an object for the duration of your entire test function, you can use patch() as a function decorator. These functions are now in their own file, separate from their tests. Next, you'll re-create your tests in a file called tests.py .
read
is a method on instances of Foo
. You want to check for the mock return_value
to access the instance. After all, you create the instance by calling foo.Foo()
:
foo_instance = self.foo_mock.return_value
foo_instance.read.assert_called_once_with('foo')
Note that you are patching foo.Foo
; using bar.foo.Foo
is the same object, but a round-about way of specifying it.
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