/* * Created on Oct 7, 2005 * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. * * Copyright @2005 the original author or authors. */ package org.springmodules.cache.interceptor.caching; import junit.framework.TestCase; import org.aopalliance.intercept.MethodInvocation; import org.easymock.MockControl; import org.springmodules.AssertExt; import org.springmodules.cache.CachingModel; import org.springmodules.cache.FatalCacheException; import org.springmodules.cache.key.CacheKeyGenerator; import org.springmodules.cache.key.HashCodeCacheKeyGenerator; import org.springmodules.cache.mock.MockCachingModel; import org.springmodules.cache.provider.CacheModelValidator; import org.springmodules.cache.provider.CacheProviderFacade; import org.springmodules.cache.provider.InvalidCacheModelException; import java.beans.PropertyEditor; import java.io.Serializable; import java.lang.reflect.Method; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Properties; /** * Unit Tests for <code>{@link AbstractCachingInterceptor}</code>. * * @author Omar Irbouh * @author Alex Ruiz */ public class CachingInterceptorTests extends TestCase { protected class MockCachingInterceptor extends AbstractCachingInterceptor { CachingModel model; boolean onAfterPropertiesSetCalled; protected CachingModel model(MethodInvocation newMethodInvocation) { return model; } protected void onAfterPropertiesSet() throws FatalCacheException { onAfterPropertiesSetCalled = true; } } private static final String CACHE_ENTRY_KEY = "C-3PO"; private CacheProviderFacade cacheProviderFacade; private MockControl cacheProviderFacadeControl; private PropertyEditor editor; private MockControl editorControl; private MockCachingInterceptor interceptor; private MethodInvocation invocation; private MockControl invocationControl; private CacheKeyGenerator keyGenerator; private MockControl keyGeneratorControl; private CachingListener listener; private MockControl listenerControl; private CacheModelValidator validator; private MockControl validatorControl; public CachingInterceptorTests(String name) { super(name); } public void testAfterPropertiesSetWhenCacheModelValidatorThrowsException() { expectGetCacheModelValidator(); CachingModel model = new MockCachingModel(); Map models = new HashMap(); models.put("key", model); InvalidCacheModelException expected = new InvalidCacheModelException(""); validator.validateCachingModel(model); validatorControl.setThrowable(expected); replay(); interceptor.setCachingModels(models); try { interceptor.afterPropertiesSet(); fail(); } catch (FatalCacheException exception) { assertSame(expected, exception.getCause()); } verify(); assertFalse(interceptor.onAfterPropertiesSetCalled); } public void testAfterPropertiesSetWhenCachingModelEditorThrowsException() { expectGetCachingModelEditor(); Properties models = createModelsAsProperties(1); // create a Map of CachingModels from each of the properties. RuntimeException expected = new RuntimeException(); for (Iterator i = models.keySet().iterator(); i.hasNext();) { String key = (String) i.next(); String value = models.getProperty(key); editor.setAsText(value); editorControl.expectAndThrow(editor.getValue(), expected); } replay(); interceptor.setCachingModels(models); try { interceptor.afterPropertiesSet(); fail(); } catch (RuntimeException exception) { assertSame(expected, exception); } verify(); assertFalse(interceptor.onAfterPropertiesSetCalled); } public void testAfterPropertiesSetWithCacheProviderFacadeEqualToNull() { interceptor.setCacheProviderFacade(null); assertAfterPropertiesSetThrowsException(); } public void testAfterPropertiesSetWithCachingModelMapBeingProperties() { expectGetCachingModelEditor(); expectGetCacheModelValidator(); Properties models = createModelsAsProperties(2); // create a Map of CachingModels from each of the properties. Map expected = new HashMap(); for (Iterator i = models.keySet().iterator(); i.hasNext();) { String key = (String) i.next(); String value = models.getProperty(key); MockCachingModel model = new MockCachingModel(); editor.setAsText(value); editorControl.expectAndReturn(editor.getValue(), model); validator.validateCachingModel(model); expected.put(key, model); } replay(); interceptor.setCachingModels(models); interceptor.afterPropertiesSet(); assertEquals(expected, interceptor.models()); verify(); assertTrue(interceptor.onAfterPropertiesSetCalled); } public void testAfterPropertiesSetWithCachingModelMapEqualToNull() { interceptor.setCachingModels(null); assertAfterPropertiesSetThrowsException(); } public void testAfterPropertiesSetWithEmptyCachingModelMap() { interceptor.setCachingModels(new HashMap()); assertAfterPropertiesSetThrowsException(); } public void testAfterPropertiesSetWithNotEmptyCachingModelMapAndKeyGeneratorEqualToNull() { expectGetCacheModelValidator(); interceptor.setCacheKeyGenerator(null); Map models = new HashMap(); for (int i = 0; i < 2; i++) { models.put(Integer.toString(i), new MockCachingModel()); } for (Iterator i = models.entrySet().iterator(); i.hasNext();) { Map.Entry entry = (Map.Entry) i.next(); CachingModel model = (CachingModel) entry.getValue(); validator.validateCachingModel(model); } replay(); interceptor.setCachingModels(models); interceptor.afterPropertiesSet(); AssertExt.assertInstanceOf(HashCodeCacheKeyGenerator.class, interceptor .cacheKeyGenerator()); verify(); assertTrue(interceptor.onAfterPropertiesSetCalled); } public void testInvokeWhenCacheReturnsNullAndProceedReturnsNull() throws Throwable { setUpCachingListener(); expectMethodInvocationReturnsCacheableMethod(); Serializable key = "Luke Skywalker"; CachingModel model = expectGetFromCache(key, null); invocationControl.expectAndReturn(invocation.proceed(), null); cacheProviderFacade.putInCache(key, model, AbstractCachingInterceptor.NULL_ENTRY); listener.onCaching(key, null, model); replay(); assertNull(interceptor.invoke(invocation)); verify(); } public void testInvokeWhenCacheReturnsNullAndProceedReturnsObjectNotEqualToNull() throws Throwable { setUpCachingListener(); expectMethodInvocationReturnsCacheableMethod(); Serializable key = "Anakin Skywalker"; Object expected = new Object(); CachingModel model = expectGetFromCache(key, null); invocationControl.expectAndReturn(invocation.proceed(), expected); cacheProviderFacade.putInCache(key, model, expected); listener.onCaching(key, expected, model); replay(); assertSame(expected, interceptor.invoke(invocation)); verify(); } public void testInvokeWhenCacheReturnsNullAndProceedThrowsException() throws Throwable { expectMethodInvocationReturnsCacheableMethod(); expectGetFromCache(CACHE_ENTRY_KEY, null); Method method = MethodFactory.createCacheableMethod(); invocationControl.expectAndReturn(invocation.getMethod(), method); Exception expected = new Exception(); invocationControl.expectAndThrow(invocation.proceed(), expected); cacheProviderFacade.cancelCacheUpdate(CACHE_ENTRY_KEY); replay(); try { interceptor.invoke(invocation); fail(); } catch (Exception exception) { assertSame(expected, exception); } verify(); } public void testInvokeWhenCacheReturnsNullEntryObject() throws Throwable { expectMethodInvocationReturnsCacheableMethod(); expectGetFromCache(CACHE_ENTRY_KEY, AbstractCachingInterceptor.NULL_ENTRY); replay(); assertNull(interceptor.invoke(invocation)); verify(); } public void testInvokeWhenCacheReturnsNullWithoutCachingListeners() throws Throwable { expectMethodInvocationReturnsCacheableMethod(); Serializable key = "Luke Skywalker"; CachingModel model = expectGetFromCache(key, null); Object expected = new Object(); invocationControl.expectAndReturn(invocation.proceed(), expected); cacheProviderFacade.putInCache(key, model, expected); replay(); assertSame(expected, interceptor.invoke(invocation)); verify(); } public void testInvokeWhenCacheReturnsStoredObject() throws Throwable { expectMethodInvocationReturnsCacheableMethod(); Serializable key = "R2-D2"; Object expected = new Object(); expectGetFromCache(key, expected); replay(); assertSame(expected, interceptor.invoke(invocation)); verify(); } public void testInvokeWithNotCacheableMethod() throws Throwable { setUpMethodInvocation(); Method method = MethodFactory.createNonCacheableMethod(); invocationControl.expectAndReturn(invocation.getMethod(), method); Object expected = new Object(); invocationControl.expectAndReturn(invocation.proceed(), expected); replay(); assertSame(expected, interceptor.invoke(invocation)); verify(); } public void testInvokeWithReturnedCachingModelEqualToNull() throws Throwable { interceptor.model = null; expectMethodInvocationReturnsCacheableMethod(); Object expected = new Object(); invocationControl.expectAndReturn(invocation.proceed(), expected); replay(); assertSame(expected, interceptor.invoke(invocation)); verify(); } protected void setUp() { cacheProviderFacadeControl = MockControl .createStrictControl(CacheProviderFacade.class); cacheProviderFacade = (CacheProviderFacade) cacheProviderFacadeControl .getMock(); keyGeneratorControl = MockControl .createStrictControl(CacheKeyGenerator.class); keyGenerator = (CacheKeyGenerator) keyGeneratorControl.getMock(); interceptor = new MockCachingInterceptor(); interceptor.setCacheKeyGenerator(keyGenerator); interceptor.setCacheProviderFacade(cacheProviderFacade); } private void assertAfterPropertiesSetThrowsException() { try { interceptor.afterPropertiesSet(); fail(); } catch (FatalCacheException exception) { // we are expecting this exception. } } private Properties createModelsAsProperties(int modelCount) { String keyPrefix = "key"; String valuePrefix = "value"; Properties models = new Properties(); for (int i = 0; i < modelCount; i++) { models.setProperty(keyPrefix + i, valuePrefix + i); } return models; } private void expectGetCacheModelValidator() { validatorControl = MockControl.createControl(CacheModelValidator.class); validator = (CacheModelValidator) validatorControl.getMock(); cacheProviderFacadeControl.expectAndReturn(cacheProviderFacade .modelValidator(), validator); } private void expectGetCachingModelEditor() { editorControl = MockControl.createControl(PropertyEditor.class); editor = (PropertyEditor) editorControl.getMock(); cacheProviderFacadeControl.expectAndReturn(cacheProviderFacade .getCachingModelEditor(), editor); } private CachingModel expectGetFromCache(Serializable key, Object expected) { MockCachingModel model = new MockCachingModel(); interceptor.model = model; keyGenerator.generateKey(invocation); keyGeneratorControl.setReturnValue(key); cacheProviderFacadeControl.expectAndReturn(cacheProviderFacade .getFromCache(key, model), expected); return model; } private void expectMethodInvocationReturnsCacheableMethod() throws Exception { setUpMethodInvocation(); Method method = MethodFactory.createCacheableMethod(); invocationControl.expectAndReturn(invocation.getMethod(), method); } private void replay() { cacheProviderFacadeControl.replay(); replay(editorControl); replay(invocationControl); replay(listenerControl); keyGeneratorControl.replay(); replay(validatorControl); } private void replay(MockControl mockControl) { if (mockControl == null) { return; } mockControl.replay(); } private void setUpCachingListener() { listenerControl = MockControl.createControl(CachingListener.class); listener = (CachingListener) listenerControl.getMock(); interceptor.setCachingListeners(new CachingListener[] { listener }); } private void setUpMethodInvocation() { invocationControl = MockControl.createControl(MethodInvocation.class); invocation = (MethodInvocation) invocationControl.getMock(); } private void verify() { cacheProviderFacadeControl.verify(); verify(editorControl); verify(invocationControl); verify(listenerControl); keyGeneratorControl.verify(); verify(validatorControl); } private void verify(MockControl mockControl) { if (mockControl == null) { return; } mockControl.verify(); } }