如何在单元测试中使用 JSON 发送请求

Posted

技术标签:

【中文标题】如何在单元测试中使用 JSON 发送请求【英文标题】:How to send requests with JSON in unit tests 【发布时间】:2015-05-04 09:42:42 【问题描述】:

我在 Flask 应用程序中有代码在请求中使用 JSON,我可以像这样获取 JSON 对象:

Request = request.get_json()

这一直很好,但是我正在尝试使用 Python 的 unittest 模块创建单元测试,但我很难找到一种方法来发送带有请求的 JSON。

response=self.app.post('/test_function', 
                       data=json.dumps(dict(foo = 'bar')))

这给了我:

>>> request.get_data()
'"foo": "bar"'
>>> request.get_json()
None

Flask 似乎有一个 JSON 参数,您可以在其中设置 json=dict(foo='bar') 在 post 请求中,但我不知道如何使用 unittest 模块。

【问题讨论】:

request.data 包含什么?通常当由于输入错误导致 json 解析失败时,它会静默失败并返回 None,因此原始输入数据可能不是 json。 >>> request.get_data() '"foo": "bar"' >>> request.get_json() 无 我不太确定flask的请求是如何工作的,但似乎分离数据和json,我不知道如何将信息发送到json而不是数据,如果这有意义的话。 我认为是内容类型标头,尝试将它们设置为应用程序/json。 force 参数也很有帮助,但您可能不想去那里只是为了让单元测试通过,最好更改 mime 【参考方案1】:

自从 Flask 1.0 发布以来,flask.testing.FlaskClient 方法接受 json 参数和添加了 Response.get_json 方法,请参阅 pull request

    with app.test_client() as c:
        rv = c.post('/api/auth', json=
            'username': 'flask', 'password': 'secret'
        )
        json_data = rv.get_json()

为了兼容 Flask 0.x,您可以使用以下收据:

    from flask import Flask, Response as BaseResponse, json
    from flask.testing import FlaskClient
    
    
    class Response(BaseResponse):
        def get_json(self):
            return json.loads(self.data)
    
    
    class TestClient(FlaskClient):
        def open(self, *args, **kwargs):
            if 'json' in kwargs:
                kwargs['data'] = json.dumps(kwargs.pop('json'))
                kwargs['content_type'] = 'application/json'
            return super(TestClient, self).open(*args, **kwargs)
    

    app = Flask(__name__)
    app.response_class = Response
    app.test_client_class = TestClient
    app.testing = True

【讨论】:

别忘了 json 参数必须是 dict 而不是 JSON 字符串!【参考方案2】:

把帖子改成

response=self.app.post('/test_function', 
                       data=json.dumps(dict(foo='bar')),
                       content_type='application/json')

修复它。

感谢 user3012759。

【讨论】:

这让我很头疼。不明白为什么要在指定 application/json 内容类型时转储数据。 我相信这是因为您在帖子中发送的所有内容都必须是字符串。 令人惊讶的是这不在文档中,因为 flask 的 test_client 没有 API 文档! 如何从响应中获取数据? @variable,使用来自post 请求的响应,例如resp = client.post('/my/endpoint/',json=my_json_data),您可以使用resp.data 以字节形式访问数据。

以上是关于如何在单元测试中使用 JSON 发送请求的主要内容,如果未能解决你的问题,请参考以下文章

如何在Node.js中对使用promises和事件发射器的函数进行单元测试?

如何对正在进行的 RXJS 请求的取消进行单元测试

烧瓶单元测试:如何测试来自登录用户的请求

在单元测试中将 JSON 发布到 Flask 端点时出现错误请求 [重复]

模拟 API 响应时如何在单元测试中使用 JSON 文件

在模拟API响应时,如何在单元测试中使用JSON文件