使用pytest-mock检查呼叫顺序

问题描述

在下面显示代码段中,我想测试run()函数中的函数调用顺序,即f_3f_2之后被调用,而{{1}之后被调用}:

f_1

有什么办法可以使用class TestMock: def f_1(self) -> None: pass def f_2(self) -> None: pass def f_3(self) -> None: pass def run(self) -> None: self.f_1() self.f_2() self.f_3() 来做到这一点?我曾尝试在测试文件中模拟pytest-mockf_1f_2函数,并将f_3assert_has_calls一起使用,但是没有成功。>

在此先感谢您的帮助或提示

最好, 阿列克谢

解决方法

使用any_order=False使您处在正确的轨道上,您只需要了解attach_mock功能:

import yourmodule

def test_something(mocker):
    mock = mocker.MagicMock()
    mock.attach_mock(mocker.patch("yourmodule.TestMock.f_1"),"f_1")
    mock.attach_mock(mocker.patch("yourmodule.TestMock.f_2"),"f_2")
    mock.attach_mock(mocker.patch("yourmodule.TestMock.f_3"),"f_3")
    yourinstance = yourmodule.TestMock()
    yourinstance.run()
    mock.assert_has_calls(
        [
            mocker.call.f_1(),mocker.call.f_2(),mocker.call.f_3(),],any_order=False,)
,

我已经完全切换到unittest.mock,现在具有以下工作代码:

@mock.patch('.'.join([__name__,'TestMock','f_3']))
@mock.patch('.'.join([__name__,'f_2']))
@mock.patch('.'.join([__name__,'f_1']))
def test_order_2(f_1: mock.NonCallableMock,f_2: mock.NonCallableMock,f_3: mock.NonCallableMock) -> None:
    manager = mock.Mock()
    manager.attach_mock(f_1,'f_1')
    manager.attach_mock(f_2,'f_2')
    manager.attach_mock(f_3,'f_3')

    obj = TestMock()
    obj.run()

    manager.assert_has_calls([mock.call.f_1,mock.call.f_2,mock.call.f_3],any_order=False)

这里是问题:我不太了解属性名称的含义,因此,它们是强制性的,但对我来说唯一合理的名称是函数名称本身...我已经修改了属性名称如下:

@mock.patch('.'.join([__name__,'f_1']))
def test_order_1(f_1: mock.NonCallableMock,f_1._extract_mock_name())
    manager.attach_mock(f_2,f_2._extract_mock_name())
    manager.attach_mock(f_3,f_3._extract_mock_name())

    obj = TestMock()
    obj.run()

    manager.assert_has_calls([mock.call.f_1,any_order=False)

很高兴听到您对此的看法!

顺便说一下,为什么f_*个模拟对象是mock.NonCallableMoc类型的?我希望它们会被伪函数(Collable)取代...

再次感谢您的帮助!

最好, 阿列克谢