我有 Flaskviews.py 单元测试,它调用其他 REST API。我如何专门模拟其中一个请求?
原因是如果状态码为200,其中一个请求会触发一些操作,例如提交数据库、覆盖文件等。我想检查状态码是否会返回200。如果是,我想阻止单元测试中的后续操作,如果没有,它不会影响任何后续操作,所以不用担心。
我还希望模拟的请求根本不会影响 Flask 应用程序请求,即 Flask 应用程序请求没有被模拟。
项目/views.py
from flask import Flask
from project.another_dir.another_script import another_function
app = Flask(__name__)
@app.route('/api/abcde', methods=['POST'])
def post_something():
another_function()
项目/another_dir/another_script.py
import requests
def another_function():
response = requests.post(<some_url>) # this is the "requests" I want to mock
if response.status_code == 200:
# server working properly, commit database transaction / write to a file / trigger some other functions / ...
else:
# something's wrong with the server, send error for exception handling
单元测试
from unittest.mock import Mock
import pytest
headers = {'Authorization': 'Basic akd39K045Pw=='}
data = "some_data"
@pytest.fixture
def client():
app.testing = True
client = app.test_client()
return client
@pytest.mark.parametrize("h, d, status_code", [
(None, None, 401), # no auth header, no data
(None, data, 401), # no auth header
(headers, data, 200) # with auth header and data
])
def test_views_post_something(client, h, d, status_code):
##### This is what I want to mock to avoid actually committing to db
# from project.another_dir.another_script import requests
# mock_request = Mock()
# requests = mock_request
##### But no luck
response = client.post('/api/abcde', headers=h, data=d)
assert response.status_code == status_code
最佳答案
你试过吗pook和 unmock ?它们服务于不同的用例,但在这种情况下,听起来 pook 更适合。如果您模拟的请求不会发生太大变化并且属于私有(private)/内部 API,则 Pook 效果很好
另一种选择是使用像 docker-compose 这样的工具来使用您选择的数据库启动临时堆栈。这样,您可以让请求执行而不触及任何脆弱的资源,但如果您尝试重新创建复杂的状态,这往往会更慢并且容易出错。我通常从一种更加低接触的方法开始,例如 pook
或 unmock
,然后为最关键的任务测试构建一个临时堆栈。
关于python - 在 Python 单元测试中分别模拟多个 API 请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55481399/