I am testing a Flask application that has some SQLAlchemy models using Flask-SQLAlchemy and I'm having some problems trying to mock some models with some methods that get some models as parameters.
The toy version of what I'm trying to do is this. Suppose I have a model defined by:
// file: database.py from flask_sqlalchemy import SQLAlchemy db = SQLAlchemy() class User(db.Model): id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(80), unique=True) birthday = db.Column(db.Date)
This is imported into the application that is built using the factory application template:
// file: app.py from flask import Flask from database import db def create_app(): app = Flask(__name__) app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////tmp/test.db' db.init_app(app)
And some function that needs a User parameter like:
// file: actions.py import datetime SECONDS_IN_A_YEAR = 31556926 def get_user_age(user): return (datetime.date.today() - user.birthday).total_seconds() // SECONDS_IN_A_YEAR
In addition, there should be several views and drawings that are imported into app.py and registered in the application, which the latter calls the get_user_age function somewhere.
My problem: I want to test the get_user_age function without having to create an application, register in a fake database, etc. etc. This is not necessary, the function is completely independent of the fact that it is used in the Flask application.
So I tried:
import unittest import datetime import mock from database import User from actions import get_user_age class TestModels(unittest.TestCase): def test_get_user_age(self): user = mock.create_autospec(User, instance=True) user.birthday = datetime.date(year=1987, month=12, day=1) print get_user_age(user)
This throws me a RuntimeError: application not registered on db instance and no application bound to current context exception RuntimeError: application not registered on db instance and no application bound to current context . So I thought: βYes, I have to pay some kind of object so that it cannot check if the application is registered in the database, etc.β So I tried to decorate it with @mock.patch("database.SQLAlchemy") and other things to no avail.
Does anyone know what I should correct to prevent this behavior, or even if my test strategy is wrong?