Flask端点在正常执行时返回状态400。

问题描述 投票:1回答:1

我正在为一个函数编写单元测试,该函数处理JSON字符串中的过滤器,以利用 flask-csv. 当我在应用程序中测试该函数时,它工作得很好,用正确的过滤器触发下载,并以预期的格式返回文件。response.data 结果也很好,但我一直得到一个。BadRequest (400) 运行测试时。

这将是端点函数。

csv-download.py

import json
import logging

import flask_csv
import pandas as pd
from flask import Blueprint
from jinja2 import Template
from pydantic import ValidationError
from models import CSVModel

home_blueprint = Blueprint("home", __name__, url_prefix="/")

@home_blueprint.route("csv_download", methods=["GET", "POST"])
def download_csv():

    filter_str = request.args.get("filters")
    content = request.args.get("content")

    try:
        model = CSVModel(csv_fliters=filter_str, csv_content=content)
    except ValidationError as e:
        raise BadInputException(e.json())

    filters = json.loads(filter_str)


    with open(
        "bq_queries/myquery.bq", "r", encoding="utf-8"
    ) as file:
        query_string = file.read()

    query = Template(query_string)

    # this function is replaced by a mock.patch in the test
    data = load_from_query(apply_filters(query, filters, "None"), client)

    today = pd.Timestamp.today().strftime("%Y%m%d")
    start = pd.to_datetime(filters["order_date"][0]).strftime("%Y%m%d")
    end = pd.to_datetime(filters["order_date"][1]).strftime("%Y%m%d")

    response = flask_csv.send_csv(
        data.to_dict(orient="records"),
        f"{today}_{start}_until_{end}_{content}.csv".format(),
        list(data.columns),
    )

    return response

这个函数是这样测试的。

test_csv_download.py

import pytest  
from flask.testing import FlaskClient
from unittest.mock import patch

@patch('customer_feedback_hub.home.views.load_from_query')
def test_csv_download_(mock_load, client: FlaskClient) -> None:
    """
    Test verifying that the CSV-Download Endpoint works.

    """

    import pandas as pd
    import json

    mock_load.return_value = pd.DataFrame({'A': [1,2], 'B': [3,4]})

    test_filters = {'subentity_id': 1, 'order_date': ['2019-10-30', '2019-10-31']}

    suffix = "test"



    dl_filters = json.dumps(test_filters)

    response = client.get("/csv_download" +
    "?filters={}&content={}".format(dl_filters, suffix))

    # response format taken directly from:
    # https://github.com/Shir0kamii/Flask-CSV/blob/master/test_flask_csv.py

    expected = b"""A,B
    1,3
    2,4
    """.replace(b'\n', b"\r\n")

    response.data == expected

    assert response.status_code == 200

测试失败的消息。

====================================================================== FAILURES =======================================================================
_________________________________________________________________ test_csv_download_ __________________________________________________________________

mock_load = <MagicMock name='load_from_query' id='139751143251392'>, client = <FlaskClient <Flask 'customer_feedback_hub.app'>>

    @patch('customer_feedback_hub.home.views.load_from_query')
    def test_csv_download_(mock_load, client: FlaskClient) -> None:
        """
        Test verifying that the CSV-Download Endpoint works.

        """

        import pandas as pd
        import json

        mock_load.return_value = pd.DataFrame({'A': [1,2], 'B': [3,4]})

        test_filters = {'subentity_id': 1, 'order_date': ['2019-10-30', '2019-10-31']}

        suffix = "test"


        # start = pd.to_datetime(test_filters["order_date"][0]).strftime("%Y%m%d")
        # end = pd.to_datetime(test_filters["order_date"][1]).strftime("%Y%m%d")


        dl_filters = json.dumps(test_filters)

        response = client.get("/csv_download" +
        "?filters={}&content={}".format(dl_filters, suffix))

        # response format taken directly from:
        # https://github.com/Shir0kamii/Flask-CSV/blob/master/test_flask_csv.py

        expected = b"""A,B
        1,3
        2,4
        """.replace(b'\n', b"\r\n")

        response.data == expected

>       assert response.status_code == 200
E       assert 400 == 200
E         -400
E         +200

tests/home/test_views.py:79: AssertionError

另外,为了完整起见,定义的 CSVModel 在原始函数中使用,我用它来验证该字符串确实可以作为JSON字符串加载。

模型.py

import json

from pydantic import BaseModel, Extra, NoneStr, validator


class CSVModel(BaseModel):
    """
    Example Pydantic model for validating json
    """

    csv_filters: str
    csv_content: NoneStr = None

    class Config:
        extra = Extra.forbid

    @validator("csv_filters")
    def filters_are_json(cls, v):
        try:
            dic = json.loads(v)
            dic.items()

        except Exception:
            raise ValueError("No JSON!")

也许我漏掉了一些明显的东西,但我很高兴能有另一双眼睛在这上面。

python python-3.x flask request http-status-code-400
1个回答
0
投票

你有

response.data == expected

但你可能想

assert response.data == expected

而我怀疑这种说法会失败,并告诉你更多的信息:)

© www.soinside.com 2019 - 2024. All rights reserved.