Member-only story

Mocking GCP DatastoreRepository::performTransaction with MockK

1 min readMar 17, 2022

This is purely a quick Note To Self, so that I can find it again when googling for it 🤓

Let’s assume we’re using the integration of Google Cloud Platform for the Spring Framework and want to test the performTransaction method of the DatastoreRepository. In my case, I wanted to first fetch data and only update if a certain condition was true.

val entity = ... // whatever we want to save
myRepository.performTransaction {
val existingEntity = myRepository.findById(entity.id)
if (canOverwrite(existingEntity)) {
myRepository.save(entity)
}
}

How can we check that myRepository.save was called? You might think of using mockK’s captureLambda and lambda<>.invoke(), but this doesn’t seem to work (at least I couldn’t make it work after several hours). The thing is that the GCP library is a Java Library, and therefore expects a parameter of type java.util.functions.Function<T, R>, where a Kotlin Lambda would be of type Kotlin.Function<out R>and thus, the signatures are incompatible.

So, instead of trying to make captureLambda() work, use a regular capture(), and later call apply on the captured function directly.

val lambdaSlot =
slot<java.util.function.Function<DatastoreRepository<MyEntity, String>, Unit>>()
every { myRepository.performTransaction(capture(lambdaSlot)) } answers {
lambdaSlot.captured.apply(myRepository)
}

What happens now, is that my mocked DatastoreRepository is still a mock, but any call to performTransaction will now execute the passed lambda, and therefore I can simply check later on, that the save method was called.

verify { myRepository.save(myEntity) }

--

--

Daniel Bunte
Daniel Bunte

Written by Daniel Bunte

Leader, self-taught developer with interests in Architecture/Automation/Security.

No responses yet