如何从视图中删除“@oidc.login_required”以进行单元测试?
Posted
技术标签:
【中文标题】如何从视图中删除“@oidc.login_required”以进行单元测试?【英文标题】:How can I remove "@oidc.login_required" for unit testing from a view? 【发布时间】:2019-12-06 15:31:28 【问题描述】:我使用flask-oidc 进行用户登录,使用pytest 进行测试。对于单元测试,我想“删除”@oidc.require_login
。我该怎么做?
我尝试了什么
flask-o 的工作方式大致如下:
from flask import Flask, url_for, redirect
from flask_oidc import OpenIDConnect
app = Flask(__name__)
app.config['OIDC_CLIENT_SECRETS'] = 'client_secrets.json'
# Contents:
# Create client_id and client_secret at https://console.developers.google.com/apis/credentials
#
# "web":
# "client_id": "123456789012-abc123hi09123.apps.googleusercontent.com",
# "client_secret": "ab123456789ABCDEFGHIJKLM",
# "redirect_uris": ["http://localhost:5000"],
# "auth_uri": "https://accounts.google.com/o/oauth2/auth",
# "token_uri": "https://accounts.google.com/o/oauth2/token",
# "userinfo_uri": "https://www.googleapis.com/oauth2/v3/userinfo"
#
#
app.config['SECRET_KEY'] = 'uq4aKjUvWXTPTIyfCz7mTtcG'
app.config['OIDC_ID_TOKEN_COOKIE_SECURE'] = False
app.config['OIDC_SCOPES'] = ["openid", "profile", "email"]
app.config['OIDC_CALLBACK_ROUTE'] = '/authorization-code/callback'
oidc = OpenIDConnect(app)
@app.route('/')
@oidc.require_login
def index():
return redirect(url_for('personalized'))
@app.route('/personalized')
@oidc.require_login
def personalized():
info = oidc.user_getinfo(['email', 'openid_id'])
return 'Hello, ()'.format(info.get('email'), info.get('openid_id'))
@app.route('/hello')
@oidc.require_login
def constant():
return 'Hello'
if __name__ == '__main__':
app.run(port=5000)
然后我希望单元测试可以模拟掉@oidc.require_login
:
# core modules
from unittest import mock
# 3rd party modules
import pytest
# internal modules
import exampleapp
@pytest.fixture
def client():
app = exampleapp.app
client = app.test_client()
yield client
@mock.patch("flask_oidc.OpenIDConnect")
def test_private(mock_require_login, client):
rv = client.get('/hello')
assert rv.data == b'Hello'
【问题讨论】:
【参考方案1】:首先通过 pip 安装 blinker
。我不知道为什么,但它是必需的。
那么这对我有用:
# core modules
from unittest import mock
# 3rd party modules
import pytest
from flask import appcontext_pushed, g
# internal modules
import exampleapp
@pytest.fixture
def client():
app = exampleapp.app
app.testing = True
app.before_request_funcs[None] = []
def handler(sender, **kwargs):
g.oidc_id_token = 'sub': 'some-user-id', 'email': 'foo@bar.com'
client = app.test_client()
with appcontext_pushed.connected_to(handler, app):
yield client
def test_private(client):
with mock.patch.object(
exampleapp.oidc, "validate_token", return_value=True
):
rv = client.get('/hello')
assert rv.data == b'Hello'
灵感来自https://github.com/fedora-infra/elections
【讨论】:
以上是关于如何从视图中删除“@oidc.login_required”以进行单元测试?的主要内容,如果未能解决你的问题,请参考以下文章