简体   繁体   English

使用login_required对flask瓶测试进行单元测试

[英]unit testing flask app with login_required

I have the following test case for my flask app setup 我的烧瓶应用程序设置有以下测试用例

class AboutViewTest(BaseTestCase):
    def setUp(self):
        self.url = url_for('pages_app.about',_external=True)
        self.url_login_redirect = url_for('accounts_app.login')

    def test_render(self):
        # without login
        resp = self.client.get(self.url)
        self.assertRedirects(resp, self.url_login_redirect)

        # after login
        with self.app.test_client() as c:
            login_successful = self.login(username='user1', password="123456", client=c)
            self.assertTrue(login_successful)
            resp = c.get(self.url)
            self.assertStatus(resp, 200) # this fails

To test a view with @login_required 使用@login_required测试视图

@pages_app.route('/about/')
@login_required
def about():
    return render_template('pages/about.html')


def login_required(f):
    @wraps(f)
    def decorated_function(*args, **kwargs):
        if g.user is None:
            return redirect(url_for('accounts_app.login', next=request.url))
        return f(*args, **kwargs)
    return decorated_function

The second test case fails (login required) as it gets redirected to login 302 != 200 第二个测试用例失败(需要登录),因为它被重定向到登录302 != 200

How can I test this view with to pass both the cases(with and without login)? 如何测试此视图以传递两种情况(使用和不使用登录)? Wht are the best practices to do this? 这是最好的做法吗?

The best approach is probably to populate your g.user variable as suggested in the Flask docs : 最好的方法可能是按照Flask文档中的建议填充g.user变量:

def get_user():
    user = getattr(g, 'user', None)
    if user is None:
        user = fetch_current_user_from_database()
        g.user = user
    return user

Obviously, you have to define fetch_current_user_from_database() , where you'll instantiate a user (you have a User class, I assume) and return it. 显然,你必须定义fetch_current_user_from_database() ,你将实例化一个用户(我假设你有一个User类)并返回它。 Then just call get_user() to instantly have a user logged in when needed. 然后只需调用get_user()即可让用户在需要时立即登录。

As an alternative, you can add a flag to your settings to disable login and use it in your login_required method when testing. 作为替代方案,您可以在设置中添加标志以禁用登录,并在测试时在login_required方法中使用它。

For example: 例如:

from flask import current_app

def login_required(f):
    @wraps(f)
    def decorated_function(*args, **kwargs):
        if not current_app.config.get('LOGIN_DISABLED', False) and g.user is None:
            return redirect(url_for('accounts_app.login', next=request.url))
        return f(*args, **kwargs)
    return decorated_function

Then in your test: 然后在你的测试中:

def test_render(self):
    # without login
    resp = self.client.get(self.url)
    self.assertRedirects(resp, self.url_login_redirect)

    self.app.config['LOGIN_DISABLED'] = True

    resp = c.get(self.url)
    self.assertStatus(resp, 200)

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

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