Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

mock.patch not working in pytest fixture?

Tags:

python

pytest

I need to write test case for f2() in the following mod1.

mod1.py:

from mod_x import X

def f1():
    raise Exception('Test shouldn''t call real f1()')

def f2():
    f1()

And the following is the imported mod_x.

mod_x.py

class Y:
    def func2(self):
        raise Exception("Shouldn't be called")

class X:
    def __init__(self):
        self.producer = Y()

Here is the test code test_mod1.py. It suppose to patch mod1.f1 so the real f1() shouldn't be called.

import mod1
import pytest
from unittest import mock

@pytest.fixture()
@mock.patch('mod1.f1')
def patched_mocked(mocked_function):
    x_mock = mock.Mock(mod1.X)
    x_mock.producer = mock.Mock()
    x_mock.producer.func2 = lambda : None
    mocked_function.return_value = x_mock
    return x_mock   

def test_1(patched_mocked):
    mod1.f2() # f2() shouldn't call the real f1() because of patching
    # assert ....

def test_2(patched_mocked):
    mod1.f2()
    # assert ....

However,

test_mod1.py FF                                                                                                                                                                                                      [100%]

======================================================================================================== FAILURES ========================================================================================================= 
_________________________________________________________________________________________________________ test_1 __________________________________________________________________________________________________________ 

patched_mocked_function = 

    def test_1(patched_mocked_function):
>       mod1.f2()

test_mod1.py:15:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
mod1.py:7: in f2
    f1()
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

    def f1():
>       raise Exception('Test shouldn''t call real f1()')
E       Exception: Test shouldnt call real f1()

mod1.py:4: Exception
like image 521
ca9163d9 Avatar asked Jan 19 '26 00:01

ca9163d9


1 Answers

You cannot use the patch decorator on a fixture, because the mock will be reverted at the time you return the fixture. You need to make sure that the mock is reverted (e.g. goes out of scope) only after the test ends (e.g. after the fixture lifetime):

@pytest.fixture()
def patched_mocked():
    with mock.patch('mod1.f1') as mocked_function:
        x_mock = mock.Mock(mod1.X)
        x_mock.producer = mock.Mock()
        x_mock.producer.func2 = lambda: None
        mocked_function.return_value = x_mock
        yield x_mock

In this case the mock is reverted only after the yield returns, which is after the test has finished.

like image 114
MrBean Bremen Avatar answered Jan 22 '26 02:01

MrBean Bremen



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!