unittest.mock 在使用 pytest 进行测试 运行 时不起作用

unittest.mock doesn't work when tests are run with pytest

我有以下项目结构:

tests/
└── messenger/
    └── messaging_test.py
app/
├── __init__.py
├── models.py
└── messenger/
    ├── __init__.py
    └── messaging.py

messaging.py 模块中有一个函数 send_schedule 包含以下几行:

talks = models.Talk.query.all()
raise ValueError(str(talks))  # the debug output

我正在尝试修补 models.Talk.query.all() 调用。在 messaging_test.py 中有以下测试:

@patch('app.models.Talk.query.all')
def test_send_schedule(self, all_query_mock):
    all_query_mock.return_value = []
    for talk_id in range(1, 6):
        talk_mock = MagicMock(id=talk_id, title=str(talk_id), speaker_facebook_id=1)
        all_query_mock.return_value.append(talk_mock)
    with vcr.use_cassette('vcr_cassettes/send_schedule.yaml'):
        response = messaging.send_schedule(self.access_token, self.user_id)

    self.assertTrue('recipient_id' in response)
    self.assertTrue('message_id' in response)
    self.assertEqual(response['recipient_id'], self.user_id)

当我 运行 使用 python3 -m pytest tests/messenger/messaging_test.py 命令进行测试时,ValueError 输出一个空列表,这表示调用未被修补。你能建议解决这个问题吗?

我做了什么来解决这个问题:

好吧,我显然对此进行了糟糕的研究。 pytest 模块没有问题。为了解决这个问题,我需要修补 app.models.Talk,而不是奇怪的 app.models.Talk.query.all。在我修补 class 之后,我简单地添加了我需要的属性:

    @patch('app.models.Talk')
def test_send_schedule(self, talk_class_mock):
    talk_mocks = []
    for talk_id in range(1, 6):
        talk_mock = MagicMock(id=talk_id, title=str(talk_id), speaker_facebook_id=1)
        talk_mocks.append(talk_mock)
    query_mock = MagicMock(all=MagicMock(return_value=talk_mocks))
    talk_class_mock.query = query_mock
    with vcr.use_cassette('vcr_cassettes/send_schedule.yaml'):
        response = messaging.send_schedule(self.access_token, self.user_id)

    self.assertTrue('recipient_id' in response)
    self.assertTrue('message_id' in response)
    self.assertEqual(response['recipient_id'], self.user_id)