0

I'm somewhat new to mocking for unit tests.

I have some code like this:

In foo/bar/baz.py I have 2 functions I want to mock, one calls the other:

def function1_to_mock():
.    
.    
.

def function2_to_mock(): 
    function1_to_mock()

In foo/bar/main.py I import 1 of these and call it:

from .baz import function2_to_mock

def some_function(): 
    function1_to_mock()
    .
    .
    .

I want to mock both function1_to_mock and function2_to_mock

In my test I do this:

def function1_to_mock(kid): 
    return MOCKED_VALUE

@pytest.fixture(autouse=True) 
def mock_dependencies(): 
    with patch(foo.bar.baz.function1_to_mock') as mock_function1_to_mock, \ 
      patch('foo.bar.main.function2_to_mock') as mock_function2_to_mock: 
        mock_function2_to_mock.return_value = {
            'this': 'that
        } 
    yield mock_function1_to_mock, mock_function2_to_mock

def test_main(mock_dependencies): 
    some_function()

When some_function is called the real function1_to_mock and function2_to_mock are called instead of my mock.

Can someone please let me know how to properly mock these 2 functions.

1 Answer 1

0

I have modified a bit your code and I don't have used pytest but only the module unittest. Your baz.py file has become (not far from your: I have added only the print instruction):

def function1_to_mock():
    print("REAL function1")
    
def function2_to_mock():
    print("REAL function2")
    function1_to_mock()

In your main.py I have changed only the import instruction as following:

from baz import function2_to_mock

def some_function():
    function2_to_mock()

I have created the file test.py in the folder foo/bar/test.py:

from main import some_function
import unittest
from unittest.mock import patch

def f1_mock():
    print('F1_MOCKED')

def f2_mock():
    print('F2_MOCKED')

class MyTestCase(unittest.TestCase):
    def test_main(self):
        with patch('baz.function1_to_mock') as mock_function1_to_mock:
            with patch('main.function2_to_mock') as mock_function2_to_mock:
                mock_function1_to_mock.side_effect = f1_mock()
                mock_function2_to_mock.side_effect = f2_mock()
                some_function()

    def test_main_real_func(self):
        some_function()

if __name__ == '__main__':
    unittest.main()

The output of the execution in my system is the following:

F1_MOCKED
F2_MOCKED
REAL function2
REAL function1
..
----------------------------------------------------------------------
Ran 2 tests in 0.001s

OK

The previous output shows that the test method test_main() calls the mocked function f1_mock() and f2_mock(), while the test method test_main_real_func() calls the real function (function1_to_mock() and function2_to_mock). In this test I have used side_effect instead of return_value.

This is one of the possible ways to substitute real function with mock functions. I hope my code could be useful for you.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.