I have several interacting classes.
In a test file for one of these classes, I first patch an object inside a context manager, change some of its returns, and run a test.
This causes a different test, outside that context manager, to fail, and fail because of the changed returns.
I tried making a MNWE. Here is a simple example of what the structure of this MNWE looks like:
patchtest
|- __init__.py
|- ClassToBeMocked.py
|- MiddleClass.py
|- LastClass.py
|- test_LastClass.py
|- test_MiddleClass.py
(the real app is divided into separate source and test directories)
Here's what the files look like:
# ClassToBeMocked.py
class _ClassToBeMocked():
def execute(self):
return "original class"
ClassToBeMocked = _ClassToBeMocked() # note singleton
# MiddleClass.py
from patchtest.ClassToBeMocked import ClassToBeMocked
class MiddleClass():
def execute(self):
return {"name" : ClassToBeMocked.execute()}
# LastClass.py
from patchtest.MiddleClass import MiddleClass
class LastClass():
def __init__(self):
self.middleClass = MiddleClass()
def execute(self):
data = self.middleClass.execute()
return data["name"]
# test_LastClass.py
from patchtest.LastClass import LastClass
def test_last_class():
lastClass = LastClass()
assert "original class" == lastClass.execute()
# test_MiddleClass.py
import unittest.mock as mock
from patchtest.MiddleClass import MiddleClass
with mock.patch('patchtest.ClassToBeMocked') as MockedClass:
MockedClass.execute.return_value = "mocked class"
def test_middle_class():
middleClass = MiddleClass()
data = middleClass.execute()
assert MockedClass.execute.called
assert data["name"] == "mocked class"
This is my best attempt at a MNWE with the same structure.
The problem in my application is that test_last_class
is failing when middleClass.execute()
returns "mocked class". If I remove text_MiddleClass.py
and re-run pytest, then everything works fine. For some reason, the mocked object is not being restored.
(Note: this MNWE is failing for a different reason, where MockedClass
is not replacing ClassToBeMocked
at all. That is not the problem in my application, and I don't know why either failure is occurring)
In my application there are many unit tests. Yet another unit test uses the exact same method to patch the exact same class, and has never had any issue.
I expect for ClassToBeMocked
to be restored to its original value after the context manager goes out of scope.
Thanks for any help.