模拟 Class 与原始规格 Python

Mock Class with original spec Python

我正在尝试使用测试 class 中的 Mock package, specifically, using the patch decorator 在 Python 中模拟 class。

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)

我希望我的模拟具有被模拟的 class 的 原始行为 ,即除非我专门模拟 attribute/method,否则它应该表现如提供的 class(及其逻辑和 return 值)。

因此,当测试原始 class 中的现有方法而不是模拟方法时,测试应该 运行 成功而不是因以下(特定)错误而失败:

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

关于如何实现这一点有什么想法吗?

这个错误的原因,是因为一个模块被模拟了,而不是class

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

改变

@patch("mypackage.subpackage.mymodule"

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

I would like my mock to have the original behavior of the class being mocked,

恐怕是另一种方式,这将创建一个 App 的实例,并模拟所有方法和属性,它仅在您想模拟 class 尤其是 __init__ 使用一种(或两种)方法

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

I specifically mock an attribute/method, method_one, while app will have everything real except 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')

我是这样嘲笑它的:

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)