RuntimeError: working outside of application context

Question:

app.py

from flask import Flask, render_template, request,jsonify,json,g
import mysql.connector

app = Flask(__name__)
**class TestMySQL():**
  @app.before_request
  def before_request():
    try:
       g.db = mysql.connector.connect(user='root', password='root', database='mysql')
    except mysql.connector.errors.Error as err:
      resp = jsonify({'status': 500, 'error': "Error:{}".format(err)})
      resp.status_code = 500
      return resp
@app.route('/')
def input_info(self):
    try:     
        cursor = g.db.cursor()
        cursor.execute ('CREATE TABLE IF NOT EXISTS testmysql (id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, name VARCHAR(40) NOT NULL, 
                 email VARCHAR(40) NOT NULL UNIQUE)')
        cursor.close()

test.py

from app import *
class Test(unittest.TestCase):         
 def test_connection1(self):  
   with patch('__main__.mysql.connector.connect') as  mock_mysql_connector_connect:
   object=TestMySQL()
   object.before_request()  """Runtime error on calling this"  

I am importing app into test.py for unit testing.On calling ‘before_request‘ function into test.py ,it is throwing RuntimeError: working outside of application context
same is happening on calling ‘input_info()

Asked By: guri

||

Answers:

Flask has an Application Context, and it seems like you’ll need to do something like:

def test_connection(self):
    with app.app_context():
        #test code

You can probably also shove the app.app_context() call into a test setup method as well.

Answered By: brenns10

I followed the answer from @brenns10 when I ran into a similar problem when using pytest.

I followed the suggestion of putting it into test setup, this works:

import pytest
from src.app import app


@pytest.fixture
def app_context():
    with app.app_context():
        yield


def some_test(app_context):
    # <test code that needs the app context>
Answered By: Paddy Alton

I am using python3.8 and had to use a small variation to the answers already posted. I included the the below in pytests and didn’t have to change anything else in the rest of the test file.

from flask import Flask

@pytest.fixture(autouse=True)
def app_context():
    app = Flask(__name__)
    with app.app_context():
        yield

This can also be used with a context manager as well.
The main different to note here is the creation of the Flask app within the test file rather than it being imported from the main application file.

Answered By: smart.aleck
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///todo.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)

app.app_context().push()

Run in terminal
    >python
    >>>from app import app
    >>>from app import db
    >>>db.create_all()

Now it should work
Answered By: sathish