[英]Flask, flask_login, pytest: How do I set flask_login's current_user?
我正在嘗試使用 pytest 對我的 Flask 應用程序進行單元測試。 對於需要來自flask_login
的current_user
信息的端點,我有以下測試用例:
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()
with app.test_request_context():
login_user(user)
user.authenticated = True
db.session.add(user)
data = dict(
state='EXAMPLE_STATE_NAME',
action='approve'
)
resp = test_client.put(app_url_put, data=data)
assert resp.status_code == 200
在test_request_context
,我能夠正確設置current_user
。 但是,此測試失敗,因為在處理 PUT 的requests
視圖中,沒有登錄用戶和 500 錯誤結果。 錯誤消息是AttributeError: 'AnonymousUserMixin' object has no attribute 'email'
。 有人可以解釋為什么current_user
消失以及我如何正確設置它嗎?
以下是我在我的網站上的做法:
user = User.query.filter_by(user_id='xxxxxxx').one_or_none()
if user:
user.authenticated = True
db.session.add(user)
db.session.commit()
login_user(user)
else:
# here I redirect to an unauthorized page, as the user wasn't found
我不知道訂單是問題還是只是缺少db.session.commit()
,但我認為您需要同時完成這兩項工作才能使您的 put 請求db.session.commit()
。
另請注意,我正在使用one_or_none()
因為不應該有多個用戶具有相同的user_id
的可能性,只是 True 或 False 取決於是否找到了用戶。
當前session
未綁定到test_client
,因此請求使用新會話。
在客戶端設置會話 cookie,以便 Flask 可以為請求加載相同的會話:
from flask import session
def set_session_cookie(client):
val = app.session_interface.get_signing_serializer(app).dumps(dict(session))
client.set_cookie('localhost', app.session_cookie_name, val)
用法:
with app.test_request_context():
login_user(user)
user.authenticated = True
db.session.add(user)
data = dict(
state='EXAMPLE_STATE_NAME',
action='approve'
)
set_session_cookie(test_client) # Add this
resp = test_client.put(app_url_put, data=data)
從https://flask.palletsprojects.com/en/2.0.x/api/#flask.Flask.test_request_context :
這在測試期間非常有用,您可能希望運行使用請求數據的函數,而無需分派完整請求。
用法:
data = dict(
state='EXAMPLE_STATE_NAME',
action='approve'
)
with app.test_request_context(data=data): # Pass data here
login_user(user)
user.authenticated = True
db.session.add(user)
requests_process(2222) # Call function for '/requests/process/2222' directly
我的猜測是您的 PUT 請求中沒有傳遞會話 cookie。
這是我在測試期間如何記錄用戶的示例(我個人使用unittest而不是pytest ,所以我將代碼減少到嚴格的最小值,但如果您想要一個完整的unittest示例,請告訴我)
from whereyourappisdefined import application
from models import User
from flask_login import login_user
# Specific route to log an user during tests
@application.route('/auto_login/<user_id>')
def auto_login(user_id):
user = User.query.filter(User.id == user_id).first()
login_user(user)
return "ok"
def yourtest():
application.config['TESTING'] = True # see my side note
test_client = application.test_client()
response = test_client.get(f"/auto_login/1")
app_url_put = '/requests/process/2222'
data = dict(
state='EXAMPLE_STATE_NAME',
action='approve'
)
r = test_client.put(app_url_put, data=data)
在文檔中我們可以閱讀: https : //werkzeug.palletsprojects.com/en/2.0.x/test/#werkzeug.test.Client
use_cookies 參數指示是否應為后續請求存儲和發送 cookie。 默認情況下這是 True 但傳遞 False 將禁用此行為。
因此,在第一個請求GET /auto_login/1 期間,應用程序將收到一個會話 cookie 並保留它以供進一步的 HTTP 請求使用。
邊注:
在設置期間,TESTING 配置標志被激活。 這樣做是在請求處理期間禁用錯誤捕獲,以便在對應用程序執行測試請求時獲得更好的錯誤報告。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.