Sto testando un'applicazione Flask che ha alcuni modelli SQLAlchemy che usano Flask-SQLAlchemy e sto riscontrando qualche problema nel tentativo di prendere in giro alcuni modelli per alcuni metodi che ricevono alcuni modelli come parametri.Problemi nel tentativo di simulare un modello all'interno di Flask-SQLAlchemy
Una versione giocattolo di quello che sto cercando di fare è così. Supponiamo che io sono un modello dato da:
// 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)
che viene importato in un app che è costruito con il modello App Factory:
// 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)
E qualche funzione che ha bisogno di un User
come parametro:
// 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
Inoltre, nel file app.py
e nell'app devono essere presenti un paio di viste e modelli che quest'ultimo chiama la funzione get_user_age
da qualche parte.
Il mio problema è: voglio testare la funzione get_user_age
senza dover creare un'app, registrarmi con un database falso, ecc. Ecc. Che non dovrebbe essere necessario, la funzione è totalmente indipendente dal fatto che sia usato in un'app Flask.
Così ho provato:
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)
Questo mi solleva un'eccezione RuntimeError: application not registered on db instance and no application bound to current context
. Così ho pensato "sì, ovviamente devo correggere alcuni oggetti per impedirgli di controllare se l'app è registrata con il database e così via". Così ho provato a decorarlo con @mock.patch("database.SQLAlchemy")
e altre cose senza successo.
Qualcuno sa che cosa dovrei correggere per prevenire questo comportamento o anche se la mia strategia di test è completamente sbagliata?