Using both @mock.patch
decorators and
py.test fixtures can be
confusing as it’s not always clear what order arguments are being injected.
For instance, which of these is right? This:
@mock.patch.object(module, 'collaborator_1')
@mock.patch.object(module, 'collaborator_2')
def test_something_in_module(collaborator_1, collaborator_2, some_pytest_fixture):
pass
Or this?
@mock.patch.object(module, 'collaborator_2')
@mock.patch.object(module, 'collaborator_1')
def test_something_in_module(collaborator_1, collaborator_2, some_pytest_fixture):
pass
Or this?
@mock.patch.object(module, 'collaborator_2')
@mock.patch.object(module, 'collaborator_1')
def test_something_in_module(some_pytest_fixture, collaborator_1, collaborator_2):
pass
I’ve wasted considerable time using PDB to work out what is being injected where.
Not any more though. Here’s how I remember:
-
The py.test fixtures always go at the end of the argument list. Their order doesn’t matter.
-
The
@mock.patch
decorators inject arguments sequentially so the inner decorator injects the first argument, then the next outer decorator injects the second argument and so on. Like this:
@mock.patch.object(module, 'collaborator_3')
@mock.patch.object(module, 'collaborator_2')
@mock.patch.object(module, 'collaborator_1')
def test_something_in_module(collaborator_1, collaborator_2, collaborator_3):
pass
The things to remember is that it’s a symmetrical arrangement with the test function or method in the centre.
So the correct arrangement above is:
@mock.patch.object(module, 'collaborator_2')
@mock.patch.object(module, 'collaborator_1')
def test_something_in_module(collaborator_1, collaborator_2, some_pytest_fixture):
pass
–