I'm looking for the right way to test service module with temporary database. I Have a working example, but I feel like there is a better solution out there
this is an example for testing a db_service function(much more of those to check), and I'm bit annoyed by the solution I came up with, I don't want to add those lines for each db_service function now. ~ you can see the lines I added in the diff between get_categories to original_get_categories.
eventually I want to create a solid behavior of using the original app session in default running and use the session to the temp database on testing.
models.py -
from sqlalchemy.orm import declarative_base
Base = declarative_base()
class Category(Base):
__tablename__ = 'Categories'
ID = Column(Integer, primary_key=True, autoincrement=True)
Name = Column(Unicode(100))
db_service.py -
from models import Category
from app import session_scope # this is the default session my service uses to query
class DBService:
"""provide CRUD operations"""
@staticmethod
def get_categories(session=None) -> List[Category]:
if session is None:
with session_scope() as session:
categories = session.query(Category).all()
return categories
categories = session.query(Category).all()
return categories
@staticmethod
def original_get_categories() -> List[Category]:
with session_scope() as session:
categories = session.query(Category).all()
return categories
db_service_test.py -
from typing import List
from fixtures import db
from models import Category
from db_service import DBService
def test_get_all_categories(db): # uses db fixture to create new database env
first_category: Category = Category(ID=1, Name="first category")
second_category: Category = Category(ID=2, Name="second category")
session = db()
session.add(first_category)
session.add(second_category)
session.commit()
categories: List[Category] = DBService.get_categories(session)
assert len(categories) == 2
assert first_category in categories and second_category in categories
fixtures.py - it shouldn't be interesting but for any case
import pytest
from models import Base
from sqlalchemy.orm import scoped_session, sessionmaker
@pytest.fixture
def db():
engine = create_engine('sqlite:///database.sqlite3')
Base.metadata.create_all(bind=engine)
db_session = scoped_session(sessionmaker(autocommit=False, autoflush=False, bind=engine))
yield db_session
Base.metadata.drop_all(engine)
db_session().commit()