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
输出一个空列表,这表示调用未被修补。你能建议解决这个问题吗?
我做了什么来解决这个问题:
- 阅读 "Where to patch" 段文档。这让我怀疑
pytest
运行 我的测试方式很奇怪。
- 尝试使用
pytest-mock
但未能弄清楚如何将其与 unittest.TestCase
一起使用。
好吧,我显然对此进行了糟糕的研究。 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)
我有以下项目结构:
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
输出一个空列表,这表示调用未被修补。你能建议解决这个问题吗?
我做了什么来解决这个问题:
- 阅读 "Where to patch" 段文档。这让我怀疑
pytest
运行 我的测试方式很奇怪。 - 尝试使用
pytest-mock
但未能弄清楚如何将其与unittest.TestCase
一起使用。
好吧,我显然对此进行了糟糕的研究。 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)