Как мне использовать mock @patch decorator с локально импортированной библиотекой? - PullRequest
0 голосов
/ 08 октября 2019

Моя структура каталогов выглядит следующим образом:

myproject/
├── mymodule/
│   ├── foo.py
│   └── model/
│        └── functions.py
│
└── tests/
    └── footest.py

Мой foo.py файл имеет локальный импорт, который выглядит следующим образом:

from .model.functions import MyClass

Я пытаюсь смоделировать один изМетоды MyClass в одном из моих тестов, но я не могу понять, как использовать для этого декоратор @patch. Обычно я делаю это:

class CheckLambdaHandler(unittest.TestCase):
    @patch('requests.post')
    def test_post_error(self, mocked_post):
        # Test which uses requests.post

Но когда я пытаюсь сделать что-то похожее с локальным импортом, он ломается:

class CheckLambdaHandler(unittest.TestCase):
    @patch('.model.functions.MyClass.function')
    def test_post_error(self, mocked_post):
        # Test which uses requests.post

Поскольку я думаю, @patch разбивает строку на "«. что означает, что вы не можете использовать локальный импорт?

ValueError: Empty module name

Кто-нибудь еще знает, что здесь делать? Нужно ли мне изменить свой импорт? В тесте? В актуальном коде?

1 Ответ

0 голосов
/ 08 октября 2019

Из документов :

target должна быть строка в форме 'package.module.ClassName'. Цель импортируется, а указанный объект заменяется новым, поэтому цель должна импортироваться из среды, из которой вы вызываете patch().

Поскольку тестовый код обычно не находится в пакете, относительный импорт здесь не имеет смысла.

Измените целевой путь в патче (тестовый код) наиспользовать абсолютный путь. Код вашей библиотеки не нужно менять. Предполагая, что mymodule является именем пакета верхнего уровня, а myproject является корнем проекта, это будет выглядеть так:

@patch('mymodule.model.functions.MyClass.function')
...