POST接口/users单元测试返回422状态码问题排查求助
问题排查与修复方案
下面是导致测试返回422状态码的核心问题及对应修复:
1. 接口代码的语法错误(直接触发异常进入422分支)
/users接口存在多处语法、拼写错误,执行时会直接触发异常,被except:捕获后返回422:
request.get_json((多了一个左括号,应改为request.get_json()new_user = body get('user_name', None)缺少调用符,应改为new_user = body.get('user_name', None)if user_name is None:变量名不匹配,前面定义的是new_user,应改为if new_user is None:about(405)拼写错误,Flask的终止方法应为abort(405)return jsonify({'success': True )}括号闭合错误,应改为return jsonify({'success': True})- 路由定义
/users/,多了尾部斜杠,应改为/users
2. 请求字段与接口预期不匹配
测试用例传递的是username字段,但接口尝试获取的是user_name,导致new_user为None,触发后续异常:
- 要么把测试用例中
self.new_user的键名改为user_name,要么把接口逻辑改为获取username,保持字段名一致即可
3. 模型类与测试数据的细节问题
- User模型的
format方法缺少闭合大括号,补全后代码:def format(self): return { 'id': self.id, 'name': self.name, 'score': self.score } - 如果需要接收测试用例中的
score参数,接口需要从请求体中读取该值并传入User构造函数(当前接口仅传new_user作为name,score用默认值0)
4. 测试用例代码的错误
unit test.TestCase应为unittest.TestCase(去掉空格)localhos拼写错误,应改为localhostsetup_db(self.app, self database_path)变量名错误,应改为setup_db(self.app, self.database_path)self.new_user的定义缩进错误,应放在setUp方法内部- 断言代码的缩进错误,需要放在
test_create_user方法的缩进范围内 self.client = self.app.test_client应改为self.client = self.app.test_client()(提前调用方法获取客户端实例)
5. 异常捕获范围过宽
接口中except:会捕获所有异常,不利于排查问题,建议改为捕获特定异常,或者在测试环境开启调试模式查看具体错误:
from sqlalchemy.exc import SQLAlchemyError @app.route('/users', methods=['POST']) def create_user(): try: body = request.get_json() if not body: abort(400) user_name = body.get('user_name', None) if user_name is None: abort(400) # 用400更合适,表示请求参数错误,而非405方法不允许 user_score = body.get('score', 0) new_entry = User(user_name, user_score) new_entry.insert() return jsonify({'success': True}) except SQLAlchemyError: db.session.rollback() abort(422) except Exception as e: abort(400)
修正后的核心代码示例
修正后的接口代码
@app.route('/users', methods=['POST']) def create_user(): try: body = request.get_json() if not body: abort(400) user_name = body.get('user_name', None) if user_name is None: abort(400) user_score = body.get('score', 0) new_entry = User(user_name, user_score) new_entry.insert() return jsonify({'success': True}) except: abort(422)
修正后的测试用例代码
import unittest import json from your_app_module import create_app, setup_db class TriviaTestCase(unittest.TestCase): def setUp(self): self.app = create_app() self.client = self.app.test_client() self.database_path = "postgresql://postgres:postgresspass@localhost:5432/user_test_db" setup_db(self.app, self.database_path) self.new_user = { "user_name":"P.Son", "score": 0 } def test_create_user(self): res = self.client.post("/users", json=self.new_user) data = json.loads(res.data) self.assertEqual(res.status_code, 200) self.assertEqual(data['success'], True) if __name__=="__main__": unittest.main()
内容的提问来源于stack exchange,提问作者SPa
相关产品推荐
相关产品推荐

