Mock Class с оригинальной спецификацией Python - PullRequest
0 голосов
/ 02 мая 2018

Я пытаюсь смоделировать класс в Python, используя пакет Mock , в частности, используя патч-декоратор в тестовом классе.

from unittest import TestCase
from unittest.mock import Mock, patch

@patch("mypackage.subpackage.mymodule", autospec=True)
class MyClassTest(TestCase):
    def setUp(self):
        [...]

    def test_with_boundary_creates_job_flow_task(self):
        returned_value = self.some_class.return_something_from_my_module()

        self.assertIsInstance(returned_value, expected_value_class)

Я бы хотел, чтобы у моего макета было оригинальное поведение того, что имитируют класс, т. Е. Если только я не специально имитирую атрибут / метод, он должен вести себя как в предоставленном классе (с его логикой и возвращаемым значением ).

Таким образом, при тестировании не смоделированного метода, но существующего метода в исходном классе, тест должен выполняться успешно, а не завершаться с ошибкой (определенной):

AssertionError: <class 'unittest.mock.MagicMock'> is not an instance of <class 'airflow.contrib.operators.emr_create_job_flow_operator.EmrCreateJobFlowOperator'>

Есть идеи о том, как этого добиться?

Ответы [ 2 ]

0 голосов
/ 03 мая 2018

Я издеваюсь так:

from mypackage.subpackage.mymodule import MyClass

class MyClassTest(TestCase):
    def setUp(self):
        [...]

    @patch.object(MyClass, 'method_to_mock', autospec=True)
    def test_with_boundary_creates_job_flow_task(self, mock_method):
        mock_method.return_value = expected_value_class() # Can use a stub
        returned_value = self.some_class.return_something_from_my_module()

        self.assertIsInstance(returned_value, expected_value_class)
0 голосов
/ 03 мая 2018

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

AssertionError: <class 'unittest.mock.MagicMock'> is not an instance of 
<class ...EmrCreateJobFlowOperator'>

Изменение

@patch("mypackage.subpackage.mymodule"

К

@patch("mypackage.subpackage.mymodule.SomeClass"

Мне бы хотелось, чтобы в моем макете было оригинальное поведение насмешливого класса,

Боюсь, что все наоборот, это создаст экземпляр App со всеми насмешенными методами и атрибутами, это полезно только тогда, когда вы хотите смоделировать класс, особенно __init__, чтобы использовать один метод (или два)

mock_app = MagicMock(name='App', spec=App)
mock_app.method_one.return_value = whatever

Я специально высмеиваю атрибут / метод method_one, тогда как app будет иметь все реальное, кроме method_one

mock_app = MagicMock(name='App', 'method_one', spec=App)
mock_app.method_one.return_value = 'mocked value'
app = App()

Короче, ваш патч будет

  from airflow.contrib.operators.emr_create_job_flow_operator import EmrCreateJobFlowOperator
  @patch.object(EmrCreateJobFlowOperator, 'the_method')
...