检查私有类方法调用顺序

时间:2018-05-13 10:50:09

标签: python python-3.x unit-testing mocking python-mock

您好!

  

Tl; dr :我需要检查公共类方法是否按特定顺序调用私有类方法,具体取决于某些条件。我怎么能这样做?

考虑有这样的课程:

class SomeClass(object):

    def __init__(self, param: ParamsEnum):
        self._param = param

    def process(self):
        if self._param == ParamsEnum.VALUE_1:
            self._do_intermediate_process()
        self._do_process()

    def _do_process(self):
        raise NotImplementedError

    def _do_intermediate_process(self):
        pass

我想写一个单元测试来检查过程逻辑。我尝试了几种方法,但没有一种方法成功。

接近一个 - 使用单独的Mock()作为容器。

@mock.patch.object(SomeClass, '_do_process')
@mock.patch.object(SomeClass, '_do_intermediate_process')
def test_process(self, mocked_do_process, mocked_do_intermediate_process):
    mock_container = Mock()
    mock_container.m0, mock_container.m1 = mocked_do_process, mocked_do_intermediate_process

    instance = SomeClass(ParamsEnum.VALUE_1)
    instance.process()

    mocked_do_process.assert_called_once()
    mocked_do_intermediate_process.assert_called_once()
    mock_container.assert_has_calls([mock_container.m0, mock_container.m1])

因此,mock_container.method_calls没有显示任何内容。

接近两个 - 模仿'过程',保持原始逻辑为副作用。无论最后一行的模拟方法顺序如何,都会通过此测试。

@mock.patch.object(SomeClass, '_do_process')
@mock.patch.object(SomeClass, '_do_intermediate_process')
def test_process(self, mocked_do_process, mocked_do_intermediate_process):
    origignal_process = SomeClass.process
    with mock.patch.object(SomeClass, 'process', autospec=True) as mocked_process:
        def side_effect(self):
            return origignal_process(self)
        mocked_process.side_effect = side_effect

        class_mock = Mock(spec=SomeClass, autospec=True)
        class_mock.process = mocked_process
        class_mock._do_process = mocked_do_process
        class_mock._do_intermediate_process = mocked_do_intermediate_process
        class_mock._param = ParamsEnum.VALUE_1

        class_mock.process(class_mock)

        mocked_do_process.assert_called_once()
        mocked_do_intermediate_process.assert_called_once()
        mocked_process.assert_called_once()
        class_mock.assert_has_calls([mocked_do_intermediate_process, mocked_do_process])

0 个答案:

没有答案