如何在烧瓶模板中模拟`current_user`?

时间:2017-11-14 20:05:28

标签: python flask jinja2 flask-login

我想在模板渲染下模仿flask-login' s current_user。此函数返回当前登录的用户。

现在我正在嘲笑AnnonymousUserMixin中的flask-login,如果用户未经过身份验证,则默认返回该current_user。但这导致各种各样的玩杂耍。如果我可以简单地模拟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): ... 我将能够创建一个Mocked对象以便它返回。

以下是我今天使用的示例:

async

此致

2 个答案:

答案 0 :(得分:5)

好。我找到了答案。

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

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

此处_get_user在同一模块中定义。我在current_user模拟_get_user时模仿flask_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

此致

答案 1 :(得分:0)

我在 The Test 一节中发现了这个tutorial

它说:

  

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

简单来说,您可以通过邮寄请求登录您的用户,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())