I'm writing a unit test to verify my caching works as expected by reducing the number of calls to the database and using the cache itself only. I use caffeine caching for this purpose. The problem is, I can't fill the cache with value even though I call the method annotated with @Cacheable
I believe I don't have to share CacheProperties details because it's just a POJO class for reading application.yml file. It's working just fine. Could it be possible that I'm having this error because of the mock?
Repository Interface
interface MyRepo : Repository<Any, Any> {
@Cacheable("myCache")
fun findId(id: String): String
}
Cache Configuration
@EnableCaching
@Configuration
class CacheConfiguration(
private val cacheProperties: CacheProperties,
) {
@Bean
fun cacheManager(): CacheManager {
val caffeineCacheManager = CaffeineCacheManager()
cacheProperties.caches.map { config ->
caffeineCacheManager.registerCustomCache(
config.name,
buildCache(Duration.parse(config.ttl)),
)
}
return caffeineCacheManager
}
private fun buildCache(ttl: Duration) =
Caffeine.newBuilder().expireAfterWrite(ttl.toJavaDuration()).build<Any, Any>()
}
Unit Test
@SpringBootTest
@EnableConfigurationProperties
@ContextConfiguration(classes = [CacheConfiguration::class, CacheProperties::class])
class MyRepoTest {
@Autowired
lateinit var cacheManager: CacheManager
private val myRepo = mockk<MyRepo>()
@Test
fun methodInvocationShouldBeCached() {
val first = String()
val second = String()
every { myRepo.findId(any()) }.returnsMany(
first,
second,
)
// First invocation returns object returned by the method
assertEquals(
first,
myRepo.findId("foo"),
)
// Verify cache was populated
assertNotNull(cacheManager.getCache("myCache")!!["foo"])
// Second invocation should return cached value, *not* second (as set up above)
assertEquals(
first,
myRepo.findId("foo"),
)
// Verify repository method was invoked once
verify(exactly = 1) { myRepo.findId("foo") }
// Third invocation with different key is triggers the second invocation of the repo method
assertEquals(
myRepo.findId("bar"),
second,
)
}
}