Skip to content
Advertisement

How to define a mock object inside a mock in python?

I have a class that contains another class in a variable. Now I want to write a unit-test and define a mock object. Therefore I define a fixture in conftest.py and monkeypatch it with the mock object. I now get a the desired mock object but the inner object is noch the mock object which I defined. The problem ist that my mock that I have created in the fixture (so that the mock returns “Bye”) will not be applied. How can I fix this and is there any better solution? See my minimal example below:

module_a.py

class Connection:
    def get(self, name):
        return f"Hello {name}"

utils.py

from main.module_a import Connection

class Util:
    def __int__(self):
        self.conn: Connection = Connection()

module_main.py

from main.utils import Util

def main() -> str:
    util: Util = Util()
    msg: str = util.conn.get(name="Joe")
    return msg

conftest.py

from unittest.mock import Mock
import pytest
from main.module_a import Connection
from main.utils import Util

@pytest.fixture(scope="function")
def util_mock(monkeypatch):
    conn_mock: Mock = Mock(spec=Connection)
    conn_mock.get.return_value = "Bye"

    util_mock: Mock = Mock(spec=Util, conn=conn_mock)
    monkeypatch.setattr(target="main.module_main.Util", name=util_mock)
    return util_mock

test_module_main.py

from unittest.mock import Mock
from main import module_main

def test_main(util_mock: Mock):
    msg: str = module_main.main()
    test: str = util_mock.conn.get(name="foot")
    assert test == "Bye"  # work right afer fixture insertion
    assert msg == "Bye"  # fails after a new object is created

Advertisement

Answer

Found a solution myself. When a new object is created (Util()) __call__ is triggered and returns a new object of the mock, hence all defined properties are lost. We just need to return the mock object itself with util_mock.return_value = util_mock.

User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement