Giving a talk about not using mocks, I mentioned that the golden rule to use patch is to always apply it on the place the object was used. There were other possiblilities suggested by one attendee so I decided to validate if that rule is still valid or not.
The files a.py
, b.py
, c.py
, d.py
try to generate all possible scenarios for importing a module and using it's functions, and test.py
tries to combine all possible ways of patching.
The output is this:
> python test.py
.F...F..........
======================================================================
FAIL: test_func1_calls_some_function_on_b (__main__.Test)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/hernantz/.virtualenvs/test/local/lib/python2.7/site-packages/mock.py", line 1201, in patched
return func(*args, **keywargs)
File "test.py", line 78, in test_func1_calls_some_function_on_b
mocked.assert_called_with()
File "/home/hernantz/.virtualenvs/test/local/lib/python2.7/site-packages/mock.py", line 831, in assert_called_with
raise AssertionError('Expected call: %s\nNot called' % (expected,))
AssertionError: Expected call: some_function()
Not called
======================================================================
FAIL: test_func2_calls_some_function_on_a (__main__.Test)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/hernantz/.virtualenvs/test/local/lib/python2.7/site-packages/mock.py", line 1201, in patched
return func(*args, **keywargs)
File "test.py", line 83, in test_func2_calls_some_function_on_a
mocked.assert_called_with()
File "/home/hernantz/.virtualenvs/test/local/lib/python2.7/site-packages/mock.py", line 831, in assert_called_with
raise AssertionError('Expected call: %s\nNot called' % (expected,))
AssertionError: Expected call: some_function()
Not called
----------------------------------------------------------------------
Ran 16 tests in 0.022s
FAILED (failures=2)
test_func1_calls_some_function_on_b
fails because the mock is being applied on b.some_function
but the some_function
is being used within a.SomeClass.some_method
, thus the mock should've been applied on a.some_function
.
test_func2_calls_some_function_on_a
fails because the mock is being applied on a.some_function
but the some_function
is being used within b.func2
, thus the mock should've been applied on b.some_function
.
Conclusion: the golden rule is still valid.
PS: I'm not sure if I covered all the cases.