Is there a way to install a mock TransactionManage...
# exposed
j
Is there a way to install a mock TransactionManager which generates no-op Transactions for component tests?
We mock out our DAOs with InMemory versions for our component tests, to keep them quick. However, that also means that we never actually connect to a DB.
I'm trying to move some transactions to a higher level than DAOs so we can group series of DB requests into single transactions, but then of course there is no TransactionManager as I've never called connect()
I can roll my own but wanted to make sure (a) I'm not following some kind of antipattern and (b) there isn't some drop-in solution for this already.
s
You seem to be asking for different things but it looks like you can install your own in
connnect(manager = yourOwnManager)
Dont think there is a test impl though
For now we just use in memory H2 instead of making custom in memory versions of everything
👌 1
j
That makes sense, we could move to H2 I guess.
Making our own no-op
TransactionManager
means implementing
newTransaction()
, means implementing a
TransactionImpl
, means incorporating a
override val connection
😕 and
Connection
is hefty
Ah I can avoid the connection with an
override val connection: Connection get() {throw ...}
Copy code
import org.jetbrains.exposed.sql.Database
import org.jetbrains.exposed.sql.Database.Companion.connect
import org.jetbrains.exposed.sql.Transaction
import org.jetbrains.exposed.sql.transactions.TransactionInterface
import org.jetbrains.exposed.sql.transactions.TransactionManager
import java.sql.Connection

fun setupTestTransactionManager() =
    connect(
        getNewConnection = { throw IllegalStateException("Should never need an actual connection for tests") },
        manager = { db -> DoNothingTransactionManager(db) })

class DoNothingTransactionManager(db: Database): TransactionManager {
    private val placeholderTransaction: Transaction = Transaction(DoNothingTransactionImpl(db))

    override var defaultIsolationLevel: Int = Connection.TRANSACTION_SERIALIZABLE

    override fun currentOrNull(): Transaction? = placeholderTransaction

    override fun newTransaction(isolation: Int): Transaction = placeholderTransaction
}

class DoNothingTransactionImpl(override val db: Database): TransactionInterface {
    override val connection: Connection
        get() { throw IllegalStateException("Should never need an actual connection for tests") }
    
    override val outerTransaction: Transaction? = null

    override fun close() {}

    override fun commit() {}

    override fun rollback() {}
}
Popping that in a @BeforeEach does the trick, feels a little hacky
s
Yes I was writing something to that accord.. but I guess it depends on your usecase and what you actually want to test but I cant image having confidence in tests not actually using a db.
j
Mmm - we've been running our in memory daos and postgres daos through the same set of tests to build confidence in their behaviour
We have pretty simple database usage as it stands. Perhaps in time it will make more sense to use H2
s
ah ok
180 Views