Reputation: 22041
While working on unittests for python application I faced interesting case when mock.patch
activate mocking via start()
method. To reproduce problem put code below into two files tests.py
and utils.py
and place them under one folder:
tests.py:
import mock
import unittest
import utils
class TestA(unittest.TestCase):
def setUp(self):
pass
def test_method_a(self):
mock.patch('utils.method_b', return_value=None).start()
actual_result = utils.method_a()
# Assertion code
def test_method_b(self):
actual_result = utils.method_b()
self.assertTrue(actual_result is None)
utils.py:
def method_a():
print 'A Method'
return method_b()
def method_b():
print 'B Method'
return True
Pay attention that test_method_a
mocking app_utils.method_b
and test_method_b
are going to call original app_utils.method_b
. I faced situation that test_method_b
cannot call actual app_utils.method_b
because it's mocked by test_method_a
.
I knew few methods of how to resolve that problem:
from app.utils import test_method_b
, - so method would leave in namespace of my test.pymock.patch
as context manager via with
statement.mock.patch
as decorator.The question is whether that possible to resolve problem without applying solutions above?
I need to keep using mock.patch
and imports
as is, if possible.
Upvotes: 1
Views: 1810
Reputation: 22041
The weird behaviour described above occurred due to not stopping of patcher which mock method_b.
See working code below:
utils.py
file is the same as in question.
tests.py
:
import mock
import unittest
import utils
class TestA(unittest.TestCase):
def setUp(self):
pass
def test_method_a(self):
method_b_patcher = mock.patch('utils.method_b', return_value=None)
method_b_patcher.start()
actual_result = utils.method_a()
method_b_patcher.stop()
def test_method_b(self):
actual_result = utils.method_b()
self.assertTrue(actual_result)
So what is updated is that in test_method_a
i've added method_b_patcher
and call start
and stop
for that patcher within test_method_a
method.
Upvotes: 1