I have a function func1() that is in production and cannot be modified. It calls a function ,function_to_be_mocked(), in another module. This takes input parameters.
I have another function func2() which calls func1().
I am writing unit tests to test func2(), and trying to mock function_to_be_mocked (as it depends on some keys I don't have (and should't have) on my local system). The only thing I can modify is test_func2().
I have a set up like the following (minimum example):
from othermodule import function_to_be_mocked
import pytest
import mock
def func1():
function_to_be_mocked(None)
def func2():
ret = func1()
print (ret)
@mock.patch('othermodule.function_to_be_mocked', return_value = 3)
def test_func2(mocker):
func2()
And othermodule.py is:
def function_to_be_mocked(arg1):
if not arg1 == 'foo':
raise ValueError
My output:
Calling func2 directly:
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/Users/blah/temp.py", line 9, in func2
ret = func1()
File "/Users/blah/temp.py", line 6, in func1
function_to_be_mocked(None)
File "/Users/blah/othermodule.py", line 3, in function_to_be_mocked
raise ValueError
ValueError
Calling test_func2() which I would expect to be mocked:
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/Users/blah/venv/lib/python2.7/site-packages/mock/mock.py", line 1305, in patched
return func(*args, **keywargs)
File "/Users/blah/temp.py", line 14, in test_func2
func2()
File "/Users/blah/temp.py", line 9, in func2
ret = func1()
File "/Users/blah/temp.py", line 6, in func1
function_to_be_mocked(None)
File "/Users/blah/othermodule.py", line 3, in function_to_be_mocked
raise ValueError
ValueError
So the mock doesn't seem to be working. Does anyone have any thoughts how to achieve this?
============ Edited below this line ===========
It doesn't sound like I can do what I thought I could (as I cannot modify anything related to function 1, or 2 in fact. All I have control over is the test.
Let me pose the following problem then as perhaps more experienced eyes than mine can see a way forward.
I have a function:
def function_to_be_tested(args):
# Some processing steps
# Function call that works locally
function_that_returns_something_1()
# Some logic
# Function call that works locally
function_that_returns_something_2()
# Function that raises an exception when running locally,
# and since I need to test the logic after this function
# (and cannot edit this code here to bypass it) I would
# (naively) like to mock it.
function_I_would_like_to_mock()
# Much more logic that follows this function.
# And this logic needs to be unit tested.
return some_value_based_on_the_logic
Tests:
def test_function_to_be_tested():
assert function_to_be_tested(args) == some_expected_value
I can easily unit test anything before function_I_would_like_to_mock().
But since this function crashes locally (and I cannot edit the code to stop it crashing locally), I feel like the correct approach would be to mock it and force a sensible return value. So that I can unit tests the code paths beyond this.
What would you suggest as a good approach?
Please note, the only thing I can modify is the test function. I can't add even decorators to the main functions.