Unit tests for Query in SQLAlchemy

your original test is on the right track, you just have to do one of two things: either make sure that two Panel objects of the same primary key identity compare as True:

import unittest

from sqlalchemy import create_engine
from sqlalchemy.orm import Session

from database.models import Base

class Panel(Base):
    # ...

    def __eq__(self, other):
        return isinstance(other, Panel) and other.id == self.id

or you can organize your test such that you make sure you’re checking against the same Panel instance (because here we take advantage of the identity map):

class TestQuery(unittest.TestCase):
    def setUp(self):
        self.engine = create_engine('sqlite:///:memory:')
        self.session = Session(self.engine)
        Base.metadata.create_all(self.engine)
        self.panel = Panel(1, 'ion torrent', 'start')
        self.session.add(self.panel)
        self.session.commit()

    def tearDown(self):
        Base.metadata.drop_all(self.engine)

    def test_query_panel(self):
        expected = [self.panel]
        result = self.session.query(Panel).all()
        self.assertEqual(result, expected)

as far as the engine/session setup/teardown, I’d go for a pattern where you use a single engine for all tests, and assuming your schema is fixed, a single schema for all tests, then you make sure the data you work with is performed within a transaction that can be rolled back. The Session can be made to work this way, such that calling commit() doesn’t actually commit the “real” transaction, by wrapping the whole test within an explicit Transaction. The example at https://docs.sqlalchemy.org/en/latest/orm/session_transaction.html#joining-a-session-into-an-external-transaction-such-as-for-test-suites illustrates this usage. Having a “:memory:” engine on every test fixture will take up a lot of memory and not really scale out to other databases besides SQLite.

Leave a Comment

Hata!: SQLSTATE[HY000] [1045] Access denied for user 'divattrend_liink'@'localhost' (using password: YES)