in Python 3.6, I use unittest.mock.patch
to patch a function like this:
class SampleTest(TestCase):
@mock.patch('some_module.f')
def test_f(self, mocked_f):
f()
mocked_f.assert_called()
This passes a mock.MagicMock()
as mocked_f
and everything works fine. However, when I want to use a custom mock object instead of the default mock.MagicMock()
using new
argument, the patch decorator does not pass the mocked object to the test_f
method. Running this code will raise a TypeError
:
class SampleTest(TestCase):
@mock.patch('some_module.f', new=lambda: 8)
def test_f(self, mocked_f):
f()
mocked_f.assert_called()
TypeError: test_f() missing 1 required positional argument: 'mocked_f'
My question is: why is this happening?
From the documentation (emphasis mine):
If
patch()
is used as a decorator and new is omitted, the created mock is passed in as an extra argument to the decorated function.
With new
being used explicitly, the decorator does not pass the mocked object as a parameter (presumably because it expects you to already have a reference that you could use without needing an argument).
In this case, a workaround would be to configure the mock after it has been passed to your test:
class SampleTest(TestCase):
@mock.patch('tests.f')
def test_f(self, mocked_f):
mocked_f.return_value = 8
# or
# mocked_f.side_effect = lambda: 8
f()
mocked_f.assert_called()