Reputation: 29229
I need to write test case for f2()
in the following mod1
.
mod1.py:
from mod_x import X
def f1():
raise Exception('Test shouldn''t call real f1()')
def f2():
f1()
And the following is the imported mod_x
.
mod_x.py
class Y:
def func2(self):
raise Exception("Shouldn't be called")
class X:
def __init__(self):
self.producer = Y()
Here is the test code test_mod1.py
. It suppose to patch mod1.f1
so the real f1()
shouldn't be called.
import mod1
import pytest
from unittest import mock
@pytest.fixture()
@mock.patch('mod1.f1')
def patched_mocked(mocked_function):
x_mock = mock.Mock(mod1.X)
x_mock.producer = mock.Mock()
x_mock.producer.func2 = lambda : None
mocked_function.return_value = x_mock
return x_mock
def test_1(patched_mocked):
mod1.f2() # f2() shouldn't call the real f1() because of patching
# assert ....
def test_2(patched_mocked):
mod1.f2()
# assert ....
However,
test_mod1.py FF [100%] ======================================================================================================== FAILURES ========================================================================================================= _________________________________________________________________________________________________________ test_1 __________________________________________________________________________________________________________ patched_mocked_function = def test_1(patched_mocked_function): > mod1.f2() test_mod1.py:15: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ mod1.py:7: in f2 f1() _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def f1(): > raise Exception('Test shouldn''t call real f1()') E Exception: Test shouldnt call real f1() mod1.py:4: Exception
Upvotes: 3
Views: 4231
Reputation: 16855
You cannot use the patch decorator on a fixture, because the mock will be reverted at the time you return the fixture. You need to make sure that the mock is reverted (e.g. goes out of scope) only after the test ends (e.g. after the fixture lifetime):
@pytest.fixture()
def patched_mocked():
with mock.patch('mod1.f1') as mocked_function:
x_mock = mock.Mock(mod1.X)
x_mock.producer = mock.Mock()
x_mock.producer.func2 = lambda: None
mocked_function.return_value = x_mock
yield x_mock
In this case the mock is reverted only after the yield
returns, which is after the test has finished.
Upvotes: 9