Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prevent touching db during unit testing with SQLAlchemy

I've been using Django for several years, but have recently decided to try out Flask for a new API. Thanks to Carl Meyers excellent presentation on testing Django at PyCon, I've been using the following technique to prevent touching the database in my Django unit tests:

cursor_wrapper = Mock()
cursor_wrapper.side_effect = RuntimeError("No touching the database!")

@patch('django.db.backends.util.CursorWrapper', cursor_wrapper)
class TestPurchaseModel(TestCase):
   '''Purchase model test suite'''
   ...

My question is can anyone tell me how to do this same basic technique with SQLAlchemy? In other words, I want any time I actually run a query against the database to produce a runtime error.

like image 347
David S Avatar asked Oct 02 '22 21:10

David S


1 Answers

You can utilize SQLAlchemy's event system for this, which allows you to use a callback when SQLAlchemy performs different events.

In your case, you would probably want to use the before_execute() or before_cursor_execute() events. For example...

from sqlalchemy import event

class TestCase(unittest.TestCase):
    def setUp(self):
        engine = ... # create or access your engine somehow
        event.listen(engine, "before_cursor_execute", self._before_cursor_execute)

    # We can also clean up the event handler after the test if we want to
    def tearDown(self):
        engine = ... # access your engine again
        event.remove(engine, "before_cursor_execute", self._before_cursor_execute)

    def _before_cusor_execute(self, conn, cursor, statement, parameters, context, executemany):
        raise RuntimeError('No touching the database!')
like image 137
Mark Hildreth Avatar answered Oct 05 '22 11:10

Mark Hildreth