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

gec*_*kos 4 python jinja2 flask flask-login

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

现在,我嘲讽 AnnonymousUserMixinflask-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):
        ...                            
Run Code Online (Sandbox Code Playgroud)

问候,

gec*_*kos 8

好的。我找到了答案。

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())
Run Code Online (Sandbox Code Playgroud)

_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()
Run Code Online (Sandbox Code Playgroud)

这是它的输出:

Hello, <flask_login.mixins.AnonymousUserMixin object at 0x7f9d5ddaaf60>
Hello, Mr Mocked
Run Code Online (Sandbox Code Playgroud)

问候,

  • 试试这个 `current_user.return_value.id = 1` 和 `current_user.return_value.role.return_value.name = 'Admin'` (2认同)