Издевательская функция python не вызывается

Я тестирую код Python (проект django 3.0.5, хотя я не думаю, что это актуально), но я не могу вызвать функции моих издевательских объектов. Вот мой код:

**myproject.mypackage.myhelpers**


def get_dict():
    return dict()

**myproject.mypackage.mythings**

from .myhelpers import get_dict


def use_dict():
    the_dict = get_dict()
    pass
    return


**myproject.tests.test_mythings**

from ..mypackage import mythings
import unittest
import unittest.mock as mock


class MyThingsTests(unittest.TestCase):

    @mock.patch('myproject.mypackage.myhelpers')
    def test_using_dict(self, mock_myhelpers):
        test_dict = {
            "hi": "foo",
            "there": "bar",
            "sir": "foobar"
        }

        mock_myhelpers.get_dict.return_value = test_dict

        mythings.use_dict()

        mock_myhelpers.get_dict.assert_called_once()

Однако в конце тест завершается с ошибкой:

AssertionError: Expected 'get_dict' to have been called once. Called 0 times


person Simen Russnes    schedule 16.07.2020    source источник


Ответы (1)


Попробуйте это вместо этого:

@mock.patch('myproject.mypackage.mythings.get_dict')
def test_using_dict(self, mock_get_dict):
    test_dict = {
        "hi": "foo",
        "there": "bar",
        "sir": "foobar"
    }

    mock_get_dict.return_value = test_dict

Раздел документации Где исправлять. немного объясняет.

Насколько я понимаю, myproject.mypackage.mythings уже импортировал настоящий get_dict до того, как вы сделаете патч. Поэтому, если вы исправите его, как @mock.patch('myproject.mypackage.myhelpers'), только модуль myhelpers будет знать, что он исправлен. Модуль mythings по-прежнему будет иметь ссылку на настоящий get_dict.

Я думаю, что альтернативой способу исправления, который я сделал выше, является изменение способа импорта вместо этого get_dict. Вместо прямого импорта get_dict просто импортируйте myhelpers и используйте get_dict как myhelpers.get_dict. Тогда вы сможете сохранить свой способ исправления, потому что get_dict будет искаться из myhelpers, у которого будет исправленный метод.

person D Malan    schedule 16.07.2020
comment
Вы совершенно правы! Или, по крайней мере, то, что вы предложили, сделало тест пройденным - person Simen Russnes; 16.07.2020
comment
Это ответ. Я хотел бы добавить, что, думая об исправлении, нужно думать об импорте во время выполнения, а не о том, как он написан. Когда вы исправляете method_a, чтобы проверить module_b, имея в module_b и import method_a from module_a, вам нужен патч @patch('module_b.method_a'). - person thlik; 26.02.2021