gpt4 book ai didi

python - 在 Flask 单元测试中覆盖 flask.g

转载 作者:太空宇宙 更新时间:2023-11-03 12:07:44 25 4
gpt4 key购买 nike

我正在尝试为使用 OpenID 进行身份验证的 flask 应用程序编写一些单元测试。由于似乎无法通过 OpenID 登录测试客户端(我问了这个问题但没有收到任何回复:Flask OpenID unittest),我想在我的测试中覆盖 g.user,所以我尝试了来自 http://flask.pocoo.org/docs/testing/#faking-resources-and-context 的代码片段并且按预期工作。

不幸的是,当使用 flask-login 时,g.user 在设置的 before_request 包装器中被覆盖

g.user = current_user

current_user 是匿名的,所以我的测试用例坏了。一种解决方法是仅在测试模式下执行 before_request 包装器代码,但您需要在生产代码中添加特定于测试的逻辑似乎很蹩脚。我也试过弄乱请求上下文,但 g.user 最终还是被覆盖了。任何解决这个问题的干净方法的想法?

最佳答案

官方文档有an example in "Faking Resources and Context" :

您首先需要确保 g.user 仅在其不存在时才被设置。您可以使用 getattr 执行此操作。这是一个稍微修改过的示例:

@APP.before_request
def set_user():
user = getattr(g, 'user', None)
if user is None:
g.user = concrete_implementation()
return user

通过使用 getattr,我们给了自己在测试期间“注入(inject)”某些东西的机会。如果我们不这样做,我们将在单元测试注入(inject)值后用具体实现再次覆盖变量。

接下来我们要做的是挂接到 appcontext_pushed 事件,并使用可测试的值设置 g.user 值。这发生在之前 before_request 钩子(Hook)。所以当 that 被调用时 getattr 将返回我们的测试值并跳过具体实现:

from contextlib import contextmanager
from flask import appcontext_pushed, g

@contextmanager
def user_set(app, user):
def handler(sender, **kwargs):
g.user = user
with appcontext_pushed.connected_to(handler, app):
yield

有了这个小 helper ,我们可以在需要使用可测试值时注入(inject)一些东西:

def test_user_me():
with user_set(app, 'our-testable-user'):
c = app.test_client()
resp = c.get('/protected-resource')
assert resp.data == '...'

关于python - 在 Flask 单元测试中覆盖 flask.g,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23164993/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com