Anatoly Bugakov
Anatoly Bugakov

Reputation: 1008

RuntimeError: working outside of request context Flask Session

I am getting RuntimeError: working outside of request context error while running a test in Flask. I've tried multiple suggestions from other threads, but none has worked for me.

Part of my views.py:

    @user_app.route('/login', methods =('GET', 'POST'))
    def login():
        form = LoginForm()
        error = None
        if form.validate_on_submit():
            user = User.objects.filter(username=form.username.data).first()
            if user:
                if bc.hashpw(form.password.data, user.password) == user.password:
                    session['username']=form.username.data
                    return 'User Logged In'
                else:
                    user = None
            if not user:
                error = 'Incorrect credentials'

        return render_template('user/login.html',form=form,error=error)

Relevant part of my tests.py:

    from application import create_app as create_app_base

    def create_app(self):
        self.db_name = 'flaskbook_test'
        return create_app_base(
            MONGODB_SETTINGS={'DB':self.db_name},
            TESTING=True,
            WTF_CSRF_ENABLED=False,
            SECRET_KEY='SecretKey'
        )

    def setUp(self):
        self.app_factory = self.create_app()
        self.app = self.app_factory.test_client()
        #self.app.application.app_context().push() <-- this did not help

    def tearDown(self):
        db = _get_db()
        db.client.drop_database(db)

    def test_login_user(self):
        #create user
        self.app.post('/register', data=self.user_dict())
        #login user
        rv = self.app.post('/login',data=dict(
            username='username',
            password='password'
        ))
        #check session is set
        with self.app as c:
            rv = c.get('/')
        assert session.get('username') == self.user_dict()['username']

I have already tried adding app_context and self.app.application.app_context().push() as mentioned above:

    with self.app.application.app_context():
        assert session.get('username') == self.user_dict()['username']

But it didn't work. Whenever I call session['username'] I get RuntimeError: working outside of request context.

My requirements.txt: Flask0.10.1 Flask-Script 2.0.5 flask-mongoengine 0.7.4

Please help.

Upvotes: 1

Views: 6394

Answers (1)

daveruinseverything
daveruinseverything

Reputation: 5167

What you want is the request context, not the app context.

Flask includes some handy functions to push a request context for you - check out the Flask testing docs and you'll see a lot of relevant info, including the test_request_context method on the app object.

Combine that with app.test_client to push a request context and then simulate client behaviour such as POSTing to your endpoint. Try this:

with self.app.test_request_context('/'), self.app.test_client() as c:
    rv = c.post('/')
    assert session.get('username') == self.user_dict()['username']

Upvotes: 1

Related Questions