【问题标题】:Set default content_type for Flask test client为 Flask 测试客户端设置默认 content_type
【发布时间】:2017-12-12 15:15:08
【问题描述】:

有没有办法在 Flask 中为测试客户端设置默认的 content_type 值?

例如,如果我有以下测试:

import unittest

class MyTestCase(unittest.TestCase):

    def setUp(self):
        from my_flask_project import app
        self.client = app.test_client()

    def test_request_one(self):
        self.client.post(
            data='{}'
            content_type='application/json'
        )

    def test_request_two(self):
        self.client.post(
            data='{}'
            content_type='application/json'
        )

我所有的测试用例都将设置content_type='application/json'。我想将 application/json 设置为请求的默认内容类型,但我找不到任何有关如何执行此操作的文档。

这样的东西是理想的:

def setUp(self):
    from my_flask_project import app
    self.client = app.test_client(
        default_content_type='application/json'
    )

【问题讨论】:

    标签: python unit-testing flask


    【解决方案1】:

    对于大多数头,你可以传递一个environ_base dict来设置其他头。但是,测试客户端将always set the Content-Type header 传递给传入的值,覆盖基数。还有environ_overrides,它可以覆盖那个覆盖,但这意味着你不能将标题设置为其他任何东西,这可能不是你想要的。

    创建一个自定义TestClient 类,如果未通过,则设置默认内容类型。将该类分配给您的 Flask 应用 test_client_class,它将在创建测试客户端时使用它。

    from flask.testing import FlaskClient
    
    class CustomClient(FlaskClient):
        def open(self, *args, **kwargs):
            kwargs.setdefault('content_type', 'application/json')
            return super().open(*args, **kwargs)
    
    app.test_client_class = CustomClient
    

    您可以将此技术用于任何 arg,而不仅仅是 content_type,包括 environ_base

    【讨论】:

      【解决方案2】:

      我发现一个更简单的解决方案是使用Client 参数json 而不是data。这样就可以明确您要发送的数据,但不需要设置/覆盖标头。

      来自烧瓶docs

      测试 JSON API 时的捷径是将 dict 传递给 json,而不是使用数据。这将自动调用 json.dumps() 并将内容类型设置为 application/json。另外,如果应用返回 JSON,response.json 会自动调用 json.loads()。

      response = client.post("/api", json={"a": "value", "b": 1})
      obj = response.json()
      

      【讨论】:

        【解决方案3】:

        扩展@davidism 的答案,Authorization 标头有一个特殊情况:使用以下形式:

        class CustomClient(FlaskClient):
            def open(self, *args, **kwargs):
                kwargs.setdefault('headers', {'Authorization': 'Bearer <token>'})
                return super().open(*args, **kwargs)
        

        【讨论】:

          猜你喜欢
          • 2011-06-05
          • 1970-01-01
          • 1970-01-01
          • 2011-08-02
          • 1970-01-01
          • 2022-01-22
          • 2021-11-27
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多