lundi 1 juin 2020

Unittest Flask Context Errors when executing sqlite queries

I am trying to populate my sqlite database in a flask unit test and I am getting the following errors on the line that executes the query:

Exception: <class 'RuntimeError'>, Working outside of request context.

This typically means that you attempted to use functionality that needed
an active HTTP request.  Consult the documentation on testing for
information about how to avoid this problem.

This is my unittest setup:

The setup method:

def setUp(self) -> None:
    # creates a test client
    self.app = app.test_client()
    app.app_context().push()
    app.config["WTF_CSRF_ENABLED"] = False
    app.config["DEBUG"] = False
    app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///" + join(_cwd, 'test_app.db')
    app.config["SQLALCHEMY_DATABASE_BINDS"] = {"test": "sqlite:///test_app.db"}
    app.config["TESTING"] = True
    app.config["SERVER_NAME"] = 'localhost.localdomain'

    db.init_app(app)
    db.drop_all()
    db.create_all()

    with app.app_context():
        db_file = join(_cwd, 'app.db.sql')
        rs = init_db_from_script(db_file)
        print(f"Result: {rs}")

    # Disable mail sending
    mail = Mail()
    mail.init_app(app)
    self.assertEqual(app.debug, False)

def tearDown(self) -> None:
    """
    Ensures that the database is emptied for next unit test
    """
    with app.app_context():
        # db.drop_all()
        pass

then test itself:

def test_graph_data_url(self):
    graph_data = [OrderedDict([('name', 'contact'), ('visits', 55)])]
    g_info = get_info_for_graph()
    app.app_context().push()
    with app.test_client() as c:
        rc = c.get('/api/get-graph-info')
    print(f"Database Path: {join(_cwd, 'app.db.sql')}")
    print(f"g_info: {g_info}")
    self.assertEqual(g_info, [])
    self.assertEqual(200, rc.status_code)

and the function that does the execution:

def init_db_from_script(script: str) -> bool:
    """Function to load data into sqlite
    database
    Parameters:
        script (str): path to sql file
    Returns:
        bool: True if successful and False otherwise
    """
    # Create an empty command string
    sql_command = ''
    with open(script, 'r') as sql_file:
        # Iterate over all lines in the sql file
        for line in sql_file:
            # Ignore commented lines
            if not line.startswith('--') and line.strip('\n'):
                # Append line to the command string
                sql_command += line.strip('\n')

                # If the command string ends with ';', it is a full statement
                if sql_command.endswith(';'):
                    # Try to execute statement and commit it
                    try:
                        with app.test_client():
                            with app.app_context():
                                session.execute(text(sql_command))
                                session.commit()

                    # Assert in case of error
                    except TypeError as t_err:
                        print("TypeError: {}".format(t_err))
                        return False
                    except ValueError as v_err:
                        print("ValueError: {}".format(v_err))
                        return False
                    except Exception as e_err:
                        print("Exception: {}, {}".format(type(e_err), e_err))
                        return False

                    # Finally, clear command string
                    finally:
                        sql_command = ''

From my debugging session the error is thrown at the line session.execute(text(sql_command)), so I am really lost as how I am to apply the "application context" in this case.

Aucun commentaire:

Enregistrer un commentaire