代码之家  ›  专栏  ›  技术社区  ›  geckos

如何在flask模板中模拟“current_user”?

  •  9
  • geckos  · 技术社区  · 7 年前

    我想嘲笑 flask-login current_user 在模板渲染下。此函数返回当前记录的用户。

    现在我在嘲笑 AnnonymousUserMixin 从…起 如果用户未经身份验证,则默认情况下返回。但这导致了各种各样的杂耍。如果我能简单地嘲笑 当前_用户 我可以创建一个模拟对象,让它返回。

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

    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):
            ...                            
    

    2 回复  |  直到 7 年前
        1
  •  10
  •   geckos    7 年前

    可以我找到了答案。

    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 在同一模块中定义。我怎么嘲笑 是模拟的 _get\u用户 flask_login.utils .

    下面是一个如何做到这一点的工作示例。我正在打印回复内容,以便人们可以看到不同的结果。真正的测试不会手动实例化测试类,应该使用 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
    

    当做

        2
  •  1
  •   Lii bob    6 年前

    我找到了这个 tutorial 对本节感兴趣 测试 .

    上面说:

    需要在请求的上下文中访问当前用户(it 是一个线程局部对象,就像烧瓶一样。请求)。什么时候 自己客户post完成请求和每个线程本地对象 被拆掉了。我们需要保留请求上下文,以便进行测试 我们与Flask登录的集成。幸运的是,Flasks test_客户端 一个上下文管理器,这意味着我们可以在with语句中使用它 只要我们需要它,它就会保持周围的环境:

    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())