繁体   English   中英

如何在flask模板中模拟`current_user`?

[英]How to mock `current_user` in flask templates?

我想在模板渲染下模拟flask-logincurrent_user 此函数返回当前登录的用户。

现在我正在使用flask-login AnnonymousUserMixin ,如果用户未经过身份验证,则默认返回。 但这导致各种各样的玩杂耍。 如果我可以简单地模拟current_user我就可以创建一个Mocked对象来返回它。

这是我今天使用的样本:

import unnittest
from flask_login.mixins import AnonymousUserMixin


class TestFoo(unittest.TestCase):
    @patch.object(AnonymousUserMixin, 'is_admin', create=True,                  
                  return_value=False)                                           
    @patch.object(AnonymousUserMixin, 'is_authenticated',  return_value=True)                                           
    def test_user_restriction(self, *args):
        ...                            

问候,

好的。 我找到了答案。

flask-login将要求您使用login_manager.init_app(your_app)初始化LoginManager实例。 执行此操作时,将current_user添加到应用程序上下文处理器。 这发生在flask_login.utils._user_context_processor函数中,该函数定义为

def _user_context_processor():
    return dict(current_user=_get_user())

这里_get_user是在同一个模块中定义的。 我要做的嘲笑current_user是模拟_get_userflask_login.utils

这是一个如何完成它的工作示例。 我正在打印响应内容,以便人们可以看到结果不同。 真正的测试不会手动实例化Test类,应该使用unittest.main或者适当的东西。

from flask import Flask, render_template_string as render_string
from flask_login import LoginManager, UserMixin

app = Flask(__name__)
loginmgr = LoginManager(app)
loginmgr.init_app(app)


class User(UserMixin):
    pass


@loginmgr.user_loader
def load_user(user_id):
    return User.get(user_id)


@app.route('/')
def index():
    return render_string('Hello, {{ current_user | safe }}')


if __name__ == '__main__':
    import unittest
    from unittest import mock

    class Test:
        def test(self):
            client = app.test_client()
            response = client.get('/')
            data = response.data.decode('utf-8')
            print(data)

        @mock.patch('flask_login.utils._get_user')
        def test_current_user(self, current_user):
            user = mock.MagicMock() 
            user.__repr__ = lambda self: 'Mr Mocked'
            current_user.return_value = user
            client = app.test_client()
            response = client.get('/')
            data = response.data.decode('utf-8')
            print(data)


    t = Test()
    t.test()
    t.test_current_user()

这是它的输出:

Hello, <flask_login.mixins.AnonymousUserMixin object at 0x7f9d5ddaaf60>
Hello, Mr Mocked

问候,

我在“测试 ”一节中发现这个教程很有趣。

它说:

需要在请求的上下文中访问current_user(它是一个线程本地对象,就像flask.request一样)。 当self.client.post完成请求并且每个线程局部对象都被拆除时。 我们需要保留请求上下文,以便我们可以测试与Flask-Login的集成。 幸运的是,Flask的test_client是一个上下文管理器,这意味着我们可以在一个语句中使用它,只要我们需要它就会保持上下文:

因此,简单来说,您可以通过post请求登录您的用户, current_user对象将可用,然后您可以在代码中测试您想要的所有内容。

这是一个例子:

with self.client:
    response = self.client.post(url_for('users.login'),
                                data={'email': 'joe@joes.com', 'password': '12345'})

    self.assert_redirects(response, url_for('index'))
    self.assertTrue(current_user.name == 'Joe')
    self.assertFalse(current_user.is_anonymous())

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM