package sagan.blog.support; import org.junit.Test; import org.springframework.aop.Advisor; import org.springframework.aop.framework.Advised; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.annotation.CacheEvict; import org.springframework.cache.annotation.Cacheable; import org.springframework.cache.interceptor.BeanFactoryCacheOperationSourceAdvisor; import org.springframework.core.annotation.AnnotationUtils; import org.springframework.util.ReflectionUtils; import saganx.AbstractIntegrationTests; import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.instanceOf; import static org.junit.Assert.*; /** * Integration tests ensuring that caching functionality works as expected in * {@link BlogService}. */ public class BlogServiceCachingTests extends AbstractIntegrationTests { @Autowired private BlogService blogService; /** * Check that {@link #blogService} is advised for caching and that all methods * relating to published posts have the {@link Cacheable} annotation. Note that while * more extensive mocking and testing through {@code MockMvc} etc is possible, this * approach is less fragile and much more concise while still being likely to catch * configuration errors. */ @Test public void blogServiceIsAdvisedForCaching() { assertThat("BlogService is not advised as expected", blogService, instanceOf(Advised.class)); boolean hasCachingAdvisor = false; for (Advisor advisor : ((Advised) blogService).getAdvisors()) { if (advisor instanceof BeanFactoryCacheOperationSourceAdvisor) { hasCachingAdvisor = true; break; } } assertTrue("BlogService is advised, but does not have caching advisor", hasCachingAdvisor); ReflectionUtils.doWithMethods(BlogService.class, (method) -> { String methodName = method.getName(); Cacheable cacheable = AnnotationUtils.findAnnotation(method, Cacheable.class); CacheEvict cacheEvict = AnnotationUtils.findAnnotation(method, CacheEvict.class); if (methodName.equals("getPublishedPost")) { assertNotNull("Method " + methodName + " was expected to have Cacheable annotation.", cacheable); String[] cacheName = cacheable.value(); assertThat(cacheName[0], equalTo(BlogService.CACHE_NAME)); } else if (methodName.equals("deletePost") || methodName.equals("updatePost")) { assertNotNull("Method " + methodName + " was expected to have CacheEvict annotation.", cacheEvict); String[] cacheName = cacheEvict.value(); assertThat(cacheName[0], equalTo(BlogService.CACHE_NAME)); } else { assertNull("Method " + methodName + " was not expected to have Cacheable annotation.", cacheable); assertNull("Method " + methodName + " was not expected to have CacheEvict annotation.", cacheEvict); } }); } }