Search code examples
pythonpython-3.xunit-testingpytestpython-unittest

Proper way to return mocked object using pytest.fixture


I'm trying to setup the target under test in @pytest.fixture and use it in all my tests in the module. I'm able to patch the test correctly, but after I add the @pytest.fixture to return the mock object and invoke the mocked object in other unit tests the object starting to refer back to the original function.

Following is the code I have. I was expecting the mocked_worker in the unit test to refer to the return value, but it is invoking the actual os.getcwd method instead.

Please help me correct the code:

import os
import pytest
from unittest.mock import patch

class Worker:
    def work_on(self):
        path = os.getcwd()
        print(f'Working on {path}')
        return path

@pytest.fixture()
def mocked_worker():
    with patch('test.test_module.os.getcwd', return_value="Testing"):
        result = Worker()
    return result

def test_work_on(mocked_worker):
    ans = mocked_worker.work_on()
    assert ans == "Testing"

Solution

  • The problem is that when the worker returns the scope of "with" statement ends making the object take its real value, the solution is to use "yield".

    @pytest.fixture()
    def mocked_worker():
        with patch('test.test_module.os.getcwd', return_value="Testing"):
            result = Worker()
            yield result