Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Python单元测试中分别模拟多个API请求_Python_Unit Testing_Mocking_Python Requests_Flask Restful - Fatal编程技术网

在Python单元测试中分别模拟多个API请求

在Python单元测试中分别模拟多个API请求,python,unit-testing,mocking,python-requests,flask-restful,Python,Unit Testing,Mocking,Python Requests,Flask Restful,我有一个Flask views.py单元测试,它调用另一个REST API。我怎样才能明确地模拟其中一个请求 原因是,如果状态代码为200,其中一个请求将触发一些操作,例如提交到数据库、覆盖到文件等。我想检查状态码是否返回200。如果是,我想阻止单元测试中的后续操作,如果不是,它不会影响任何后续操作,所以不用担心 我还希望模拟的请求根本不会影响Flask应用程序请求,即Flask应用程序请求没有被模拟 project/views.py from flask import Flask from p

我有一个Flask views.py单元测试,它调用另一个REST API。我怎样才能明确地模拟其中一个请求

原因是,如果状态代码为200,其中一个请求将触发一些操作,例如提交到数据库、覆盖到文件等。我想检查状态码是否返回200。如果是,我想阻止单元测试中的后续操作,如果不是,它不会影响任何后续操作,所以不用担心

我还希望模拟的请求根本不会影响Flask应用程序请求,即Flask应用程序请求没有被模拟

project/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()
project/other_dir/other_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
你试过了吗?它们服务于不同的用例,但在这种情况下,pook听起来更适合。如果您正在模拟的请求没有太大变化,并且是私有/内部API,那么Pook工作得很好

另一种选择是使用类似于
docker compose
的工具,使用您选择的数据库来加速短暂的堆栈。这样,您就可以让请求在不接触任何脆弱资源的情况下执行,但是如果您试图重新创建复杂的状态,这往往会变得更慢并且容易出错。我通常从一个比较低调的方法开始,比如
pook
unck
,然后为最关键的测试构建一个临时堆栈

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