Flask使用pytest测试时如何正确设置flask_login的current_user
失效原因
- 你在
test_request_context上下文内调用login_user仅会在当前上下文设置登录状态,test_client.put()发起的PUT请求会生成独立的全新请求上下文,原上下文的会话信息不会被继承,所以视图拿到的是未登录的AnonymousUserMixin对象。 - 手动修改
user.authenticated并写入数据库的操作无效:flask-login的登录状态存储在客户端会话Cookie中,而非存储在用户表字段里,该操作不会修改请求携带的会话信息。
正确设置方案
两种常用实现方式,按需选择:
方式1:通过test_client的会话上下文注入登录状态(推荐,模拟真实登录场景)
直接操作test_client的内置会话,登录状态会被同个client发起的所有请求继承:
def test_approval_logic(): with app.test_client() as test_client: app_url_put = '/requests/process/2222' # 先查询测试用户 with app.app_context(): user = User.query.filter_by(uid='xxxxxxx').first() # 操作test_client的会话,写入登录信息 with test_client.session_transaction() as sess: # flask-login默认用user_id作为会话键,对应你的User类的get_id()返回值 sess['user_id'] = user.get_id() # 可选:如果开启了会话保护,需要补充以下字段 sess['_fresh'] = True sess['_id'] = app.login_manager._session_identifier_generator() # 后续发起的请求都会携带登录会话 data = dict( state='EXAMPLE_STATE_NAME', action='approve' ) resp = test_client.put(app_url_put, data=data) assert resp.status_code == 200
方式2:Mock current_user(适合不需要验证登录逻辑,只需要固定用户信息的场景)
直接用mock替换全局的current_user对象,不需要操作会话:
from unittest.mock import patch def test_approval_logic(): with app.test_client() as test_client: app_url_put = '/requests/process/2222' with app.app_context(): user = User.query.filter_by(uid='xxxxxxx').first() data = dict( state='EXAMPLE_STATE_NAME', action='approve' ) # 发起请求时mock current_user为指定的用户对象 with patch('flask_login.utils._get_user', return_value=user): resp = test_client.put(app_url_put, data=data) assert resp.status_code == 200
内容的提问来源于stack exchange,提问作者boing
相关产品推荐
相关产品推荐

