您好!
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])