I have a class that mocks database functionality which does not subclass Mock
or MagicMock
because it defines its own __init__()
method:
class DatabaseMock():
def __init__(self, host=None):
self.host = host
self.x = {}
# other methods that mutate x
There is a function I want to test that makes an API call to the real database, so I patched it out:
from unittest.mock import patch
class TestFunctions():
def test_function(self):
with patch("path.to.database.call", DatabaseMock) as mock:
result = function_i_am_testing()
assert mock.x == result
There is a field of the DatabaseMock
called x
, but in the patch context, mock.x
returns
an AttributeError
. This leads to me believe mock
is not really an instance of DatabaseMock()
. Also, I had tried making x
a class level object which makes x
visible, but its state would persist through separate test calls which I do not want.
What is mock and how can I reference the mocked object instance in the context?
I have figured out the issue. When patch is given a class, it will return a class, not an object instance of that class.
So in my example, mock
is not a DataBaseMock
object instance, but a reference to the class. This is why class level variables are visible, but not object instance fields.
In order to get my desired functionality, I did this:
from unittest.mock import patch
class TestFunctions():
def test_function(self):
with patch("path.to.database.call") as mock:
mock.return_value = DataBaseMock()
result = function_i_am_testing()
assert mock.return_value.x == result
Now, mock is a MagicMock
object, whose return value is the object I need.