Mocking Spring TransactionTemplate with Kotlin and Mockito

Besides the @Transactional anontation, you can also use Springs TransactionTemplate programmatically.

import org.springframework.transaction.support.TransactionTemplate

class FooService constructor(
    private val transactionTemplate: TransactionTemplate
) {

    fun save() {
        transactionTemplate.execute {
            // important transactional code
        }

        // other code
    }

}

When writing a Unit-Test for this class, you probably still want to test the code that is being executed within the transaction template. To do this, you can simply mock the transaction templates method to execute whatever is inside the block.

whenever(transactionTemplate.execute(any<TransactionCallback<Unit>>())).thenAnswer {
    (it.arguments[0] as TransactionCallback<*>).doInTransaction(mock())
}

The code above uses Mockito Kotlin.

An easy way to execute any call inside the execute block is setup a @BeforeEach function from JUnit that will get called before each test execution.

import com.nhaarman.mockitokotlin2.*
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test

class FooServiceTest {

    private val transactionTemplate: TransactionTemplate = mock()

    private val fooService = FooService(
        transactionTemplate = transactionTemplate,
    )

    @BeforeEach
    fun setUp() {
        whenever(transactionTemplate.execute(any<TransactionCallback<Unit>>())).thenAnswer {
            (it.arguments[0] as TransactionCallback<*>).doInTransaction(mock())
        }
    }

    @Test
    fun `should do something`() {
        // your test code
    }

}