#4 tests: temporarily patch Flask-SQLAlchemy to use a specific connection
Merged 7 years ago by mjia. Opened 7 years ago by mjia.
mjia/waiverdb master  into  master

file modified
+9 -18
@@ -39,29 +39,20 @@ 

      request.addfinalizer(teardown)

      return db

  

- @pytest.fixture(scope='function')

- def session(db, request):

-     """Creates a new database session for a test."""

+ @pytest.yield_fixture

+ def session(db, monkeypatch):

+     """Patch Flask-SQLAlchemy to use a specific connection"""

      connection = db.engine.connect()

      transaction = connection.begin()

  

-     # https://github.com/mitsuhiko/flask-sqlalchemy/issues/345

-     class _dict(dict):

-         def __nonzero__(self):

-             return True

- 

-     options = dict(bind=connection, binds=_dict())

-     session = db.create_scoped_session(options=options)

+     # Patch Flask-SQLAlchemy to use our connection

+     monkeypatch.setattr(db, 'get_engine', lambda *args: connection)

  

-     db.session = session

+     yield db.session

  

-     def teardown():

-         transaction.rollback()

-         connection.close()

-         session.remove()

- 

-     request.addfinalizer(teardown)

-     return session

+     db.session.remove()

+     transaction.rollback()

+     connection.close()

  

  @pytest.yield_fixture

  def client(app):

Instead of replacing the whole session, we can temporarily patch Flask-SQLAlchemy
to use a specific connection to workaround this issue[1]. This will make it easier
if we want to inspect the state of the db after the test(comment out the monkeypatch
and drop_all).

[1] https://github.com/mitsuhiko/flask-sqlalchemy/issues/345

Does this mean, the monkey-patching is only temporary until that Flask issue is solved?

What will the code look like after that is solved? I assume we will always need some kind of hackery in the tests like this, if we want to inject a custom session running in its own transaction that gets rolled back etc.

Nah, I think we can still use this when the Flask issue is resolved as it's using less code and easy for us to inspect the state of the db. Right now, I have to change this options = dict(bind=connection, binds=_dict()) to options = dict(bind=connection) .

What will the code look like after that is solved? I assume we will always need some kind of

Not quite sure what you mean. This is just for patching the global scoped session to use a specific connection. The current code creates a new scoped session when running the tests, so I think it should not matter.

hackery in the tests like this, if we want to inject a custom session running in its own >transaction that gets rolled back etc.

Yeah, we still need to use the workaround for specifying the binds parameter with empty dict when creating a new scoped session. Alternatively, we may be able to monkey-patch the db.create_scoped_session() to get around this issue.

Okay gotcha. I was confused by the word "temporarily" because I thought that meant we were going to change the test fixtures again later. But I guess you mean temporarily as in, for the duration of each test.

Pull-Request has been merged by mjia

7 years ago
Metadata