Flask test_client:测试带数据的DELETE请求

9 投票
1 回答
7797 浏览
提问于 2025-04-18 08:49

我正在尝试根据http://flask.pocoo.org/docs/testing/上的建议来测试我的Flask应用,但我不知道怎么用表单数据来测试DELETE方法。

我的删除方法大概是这样的:

from flask.ext.restful import Resource, reqparse 
...
def delete(self):
    self.reqparse.add_argument('arg1', type=str, required=True, location='form')
    args = self.reqparse.parse_args()
    ...

我想用以下方式来测试:

def setUp(self):
    self.app = myApp.app.test_client()

def test_delete(self):
    rv = self.app.delete('MyEndPoint', data={'arg1', 'val'})

但是这样不行。我还查看了werkzeug.test中的EnvironBuilder的源代码,但还是不知道怎么传递数据。

1 个回答

10

我刚遇到同样的问题,主要是因为Werkzeug的测试方法目前不支持设置DELETE请求的content_type

这段代码在这里展示了Werkzeug是如何获取内容类型的:

def _get_content_type(self):
    ct = self.headers.get('Content-Type')
    if ct is None and not self._input_stream:
        if self.method in ('POST', 'PUT', 'PATCH'):
            if self._files:
                return 'multipart/form-data'
            return 'application/x-www-form-urlencoded'
        return None
    return ct

如果没有content_type,那么表单数据就无法从environ传递到请求中,这样你的Flask服务器就收不到数据。

最终,这其实是Werkzeug的一个bug,因为你可以构造一个使用DELETE方法并且包含表单数据的curl请求。我已经向Werkzeug的代码库提交了一个修复请求来解决这个问题。如果你有兴趣,可以在GitHub上参与讨论:https://github.com/mitsuhiko/werkzeug/pull/620

更新:为了在此期间解决你的问题,你可以通过在请求中明确指定内容类型来绕过这个问题,像这样:

def test_delete(self):
    rv = self.app.delete('MyEndPoint',
                         data={'arg1', 'val'},
                         headers={'Content-Type': 'application/x-www-form-urlencoded'})

再次更新:我提交的修复请求已经被审核、修改并合并,将会包含在Werkzeug的0.10版本中,希望以后就不会再出现这个问题了 :)

撰写回答