Как правильно смоделировать функцию, которая импортируется в пакет? - PullRequest
0 голосов
/ 07 октября 2019

Я пытаюсь протестировать пакет, который я создал, и для этого мне нужно смоделировать subprocess.Popen. Я хочу сделать это с помощью патч-декоратора, но не могу указать правильную цель. Я получаю ошибки, что атрибут не существует в классе.

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

.
|- package
|   |- __init__.py
|   |- package.py
|- tests
|   |- test_script.py
__init__.py

from package.package import package
package.py

from subprocess import Popen


class package:

    def __init__(self):
        self.foo = "bar"

    def echo_cmd(self):
        p = Popen("test.bat", stdout=subprocess.PIPE)
        p.wait()
        x = p.communicate()
        return x
test_script.py

import unittest
from unittest.mock import patch, Mock

import package


class TestADBHelper(unittest.TestCase):

    def setUp(self):
        self.test = package.package()


    @patch("package.Popen")
    def test_connect_to_device_not_connected(self, mock_popen):
        """test if a device can be connected"""
        process = mock_popen.return_value
        process.returncode = 0
        process.communicate.return_value = "foo"

Я хочувысмеивать вывод Попена. Я пробовал разные способы импорта и определения цели макета, но продолжаю получать ошибки вроде:

AttributeError: <module 'package' from 'C:\\Users\\***\\Documents\\mock_test\\package\\__init__.py'> does not have the attribute 'Popen'

Ответы [ 2 ]

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

Я понял это :-) Все стало ясно, когда я изменил имена всех файлов на package1, package2 и package3. Тогда приведенный выше ответ работает, как и ожидалось:

@patch("package1.package2.Popen")

Каким-то образом Python всегда импортирует класс, если имя файла совпадает с именем класса. Так вот почему он не смог найти "Popen"

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

У вас есть две вещи, называемые пакетом, и вы издеваетесь не над тем.

@patch("package.package.Popen")
...