SSCCE example here:
first_app/tests/test_file.py
from unittest.mock import patch
from django.core.management import call_command
from django.test import TestCase
class TestWierdo(TestCase):
@patch('first_app.class_a.method_to_import')
def test_b(self, mock_obj2):
call_command('this_is_command', item='abcd')
print(mock_obj2.call_args)
# prints "i should be called for test_b, call('abcd')", this is good so far
# will have issue here later.
self.assertTrue(False)
first_app/management/commands/this_is_command.py
from django.core.management import BaseCommand
from first_app.class_a import method_to_call_from_command
class Command(BaseCommand):
def add_arguments(self, parser):
parser.add_argument(
'--char',
action='store',
dest='item',
)
def handle(self, *args, **options):
char = options['item']
method_to_call_from_command(str(char))
first_app/class_a.py
from first_app.class_b import method_to_import
def method_to_call_from_command(a):
print('i should be called for test_b')
generated = method_to_import(a)
return generated
first_app/class_b.py
def method_to_import(a):
return
All is good, but let's add another test in TestWierdo class with a mistake:
class TestWierdo(TestCase):
@patch('first_app.class_a.method_to_call_from_command') <- Notice wrong mock path here.
# @patch('first_app.management.commands.this_is_command.method_to_call_from_command') <- correct one
def test_a(self, mock_obj):
call_command('this_is_command', item='test') # commenting this line also fixes the issue
print(mock_obj.call_args) # print 'test'
self.assertTrue(False)
@patch('first_app.class_a.method_to_import')
def test_b(self, mock_obj2):
call_command('this_is_command', item='abcd')
print(mock_obj2.call_args) <----- # print None !!!!, does not print "i should be called for test_b"
self.assertTrue(False)
What is going on here? It seems like the mock persists from test_a.
Commenting out call_command('this_is_command', item='test')
or wrong mock patch decorator fixes the issue.
But why does wrong mock from the test_a affect test_b?