0

I'm trying to test a @Cacheable method using the following code, but is not working, the method is not being cached, if instead of putting the @Cacheable in the getCountCache method I put it in the getCount method the test works, tried a lot of things but couldn't find the cause.

@ContextConfiguration
@ExtendWith(SpringExtension.class)
public class CacheTest {

    static class MyRepoImpl {

        private Count count;

        public MyRepoImpl(Count count){
            this.count = count;
        }

        public int getCount(String key){
            return getCountCache(key);
        }

        @Cacheable(cacheNames = "sample")
        public int getCountCache(String key) {
            return count.getCount();
        }
    }

    static class Count {
        int i = 0;
        public int getCount() {
            return i++;
        }
    }

    @EnableCaching
    @Configuration
    public static class Config {

        @Bean CacheManager cacheManager() {
            return new ConcurrentMapCacheManager();
        }

        @Bean MyRepoImpl myRepo() {
            count = Mockito.mock(Count.class);
            return new MyRepoImpl(count);
        }
    }

    static Count count;

    @Autowired MyRepoImpl repo;

    @Test
    public void methodInvocationShouldBeCached() {

        Mockito.when(count.getCount()).thenReturn(1, 2, 3, 4);

        Object result = repo.getCount("foo");
        assertThat(result).isEqualTo(1);
        Mockito.verify(count, Mockito.times(1)).getCount();

        result = repo.getCount("foo");
        assertThat(result).isEqualTo(1);
        Mockito.verify(count, Mockito.times(1)).getCount();
    }
}

1 Answers1

3

Since Spring cache works on proxy to the bean method annotated with @Cachable called from inside class won't cache. You need to call it directly from outside of the class for caching mechanism to work. Spring cache @Cacheable method ignored when called from within the same class this explanation is really good.

  • 1
    To compliment **Maciej's** answer, which is absolutely correct, and given that _Spring's Cache Abstraction_ is based on AOP (much like _Spring's Transaction Management & Transaction Demarcation_), then you can read more about why Proxy's behave this way here: https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#aop-understanding-aop-proxies – John Blum Jun 07 '21 at 18:09