Как мне откатить интеграционный тест с Slick 3 + Specs2?

Я хочу написать несколько интеграционных тестов для службы, которая запускает Slick, а затем очищает базу данных postgresql вверх, откатывая транзакцию, но я не вижу способа сделать это. Я понимаю, что могу тестировать объекты DBIO, которые были скомпонованы вместе, и откатывать их назад, но не похоже, что это возможно, если я хочу протестировать на более высоком уровне абстракции.

В псевдокоде я хочу сделать это:

StartDbTransaction() // setup
DoSomethingInDB() 
AssertSomething() 
RollBackDbTransaction() // teardown

Например, если у меня есть это (упрощено изиграть-силуэт-скользкие семена):

class PasswordInfoDAO(db: JdbcBackend#DatabaseDef) {

    // ...
    def remove(loginInfo: LoginInfo): Future[Unit] =
        db.run(passwordInfoSubQuery(loginInfo).delete).map(_ => ())

}

Я думал, что смогу написать черту ForEach по образцуРуководство по Specs2, который дает это общий пример:

// a transaction with the database
trait Transaction

trait DatabaseContext extends ForEach[Transaction] {
    // you need to define the "foreach" method
    def foreach[R: AsResult](f: Transaction => R): Result = {
        val transaction = openDatabaseTransaction
        try AsResult(f(transaction))
        finally closeDatabaseTransaction(transaction)
    }

    // create and close a transaction
    def openDatabaseTransaction: Transaction = ???

    def closeDatabaseTransaction(t: Transaction) = ???
}

class FixtureSpecification extends mutable.Specification with DatabaseContext {
    "example 1" >> { t: Transaction =>
        println("use the transaction")
        ok
    }
    "example 2" >> { t: Transaction =>
        println("use it here as well")
        ok
    }
}

Так что для гладких, я попробовал это:

override def foreach[R: AsResult](f: JdbcBackend#DatabaseDef => R): Result = {

    val db = dbConfig.db
    val session = db.createSession()
    session.conn.setAutoCommit(false)
    val result = AsResult(f(db))
    session.conn.rollback()
    result

}

Тогда я планировал использовать это примерно так:

class PasswordInfoDAOSpec(implicit ee: ExecutionEnv)
  extends Specification with DatabaseContext {

    "password" should {
       "be removed from db" in { db =>

        // arrange
        db.run(...) // something to set up the database

        // act
        PasswordInfoDAO(db).remove(loginInfo).await

        // assert
        PasswordInfoDAO(db).find(loginInfo) must be None.await
      }
   }
}

Проблема в том, что пятно 3 будет игнорировать мой сеанс (по замыслу) и вместо этого будет использовать пул сеансов, поэтому мой откат ничего не сделает. Я думаю, что у Slick есть ожидание, что вы должны использовать его на уровне DBIOActions, которые могут быть скомпонованы вместе и, возможно, выполнены в разных контекстах. Slick 2 был способ контролировать сеанс с.withSession, но это было удалено.

Является ли единственным вариантом создания, переноса и удаления тестовой базы данных с каждым тестом?

Ответы на вопрос(2)

Ваш ответ на вопрос