Flask REST API单元测试POST请求返回空值问题排查
嘿,我来帮你分析下你遇到的这个问题~
你之所以得到空的返回值,核心原因是Flask对不同Content-Type的请求数据处理逻辑不同,而你用test_client.post()的方式刚好触发了自动解析,导致request.data没有内容。
为什么request.data是空的?
当你调用client.post("/last_op/add", data={"collection": "1,2,3,4"})时,Flask的测试客户端默认会把这个字典编码成application/x-www-form-urlencoded格式(就是普通表单提交的格式)。对于这种格式的请求,Flask会自动解析数据并将其存入request.form对象中,而request.data只会保留那些Flask无法自动解析的原始请求体内容——所以这时候它自然是空的。
几种可行的解决方案
方案一:改用request.form获取表单数据
如果你的接口就是用来处理表单提交的请求,那直接修改视图函数,从request.form里取出数据即可:
@api.route("/last_op/add", methods=["GET", "POST"]) def post_add_last_operation(): # 从表单数据中获取collection字段 collection = request.form.get("collection") return collection or ""
方案二:发送原始数据并指定Content-Type
如果你确实需要从request.data获取原始请求体,那你需要直接发送字符串数据,并设置对应的Content-Type,让Flask无法自动解析:
比如发送纯文本格式的集合:
# 发送纯文本数据,指定Content-Type为text/plain response = client.post("/last_op/add", data="1,2,3,4", content_type="text/plain")
这时候视图函数里的request.data会拿到字节类型的b'1,2,3,4',如果需要字符串可以解码:
@api.route("/last_op/add", methods=["GET", "POST"]) def post_add_last_operation(): collection_str = request.data.decode("utf-8") return collection_str
方案三:发送JSON格式数据(推荐)
如果你的接口是REST风格,更推荐用JSON格式传递数据。Flask的测试客户端支持json参数,会自动设置Content-Type为application/json,并帮你序列化数据:
# 用json参数发送字典,自动转为JSON格式 response = client.post("/last_op/add", json={"collection": [1,2,3,4]})
视图函数里用request.get_json()解析数据:
@api.route("/last_op/add", methods=["GET", "POST"]) def post_add_last_operation(): # 解析JSON数据 request_data = request.get_json() collection = request_data.get("collection") return str(collection)
额外小提示:分清request的几个数据属性
request.form:存储表单编码(application/x-www-form-urlencoded)的请求数据request.data:存储Flask无法解析的原始请求体字节request.get_json():解析JSON格式(application/json)的请求数据并返回字典request.args:存储URL中的查询参数(GET请求常用)
内容的提问来源于stack exchange,提问作者dannyxn

