модульное тестирование фляги с login_required - PullRequest
0 голосов
/ 14 мая 2018

У меня есть следующий контрольный пример для настройки моего колбы

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

Чтобы проверить представление с @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

Второй тестовый пример не пройден (требуется вход в систему), поскольку он перенаправляется на вход в систему 302 != 200

Как я могу проверить это представление, чтобы пройти оба случая (с и без входа в систему)? Каковы лучшие практики для этого?

1 Ответ

0 голосов
/ 14 мая 2018

Наилучшим подходом, вероятно, является заполнение переменной g.user, как это предлагается в документах Flask :

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

Очевидно, вы должны определить fetch_current_user_from_database(), где вы будете создавать экземпляр пользователя (у вас есть User класс, я полагаю) и возвращать его. Затем просто позвоните get_user(), чтобы мгновенно войти в систему, когда это необходимо.

В качестве альтернативы, вы можете добавить флаг в ваши настройки, чтобы отключить вход в систему и использовать его в вашем методе login_required при тестировании.

Например:

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

Тогда в вашем тесте:

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