1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.springframework.cache.interceptor;
18
19 import java.lang.reflect.Method;
20 import java.util.Collection;
21 import java.util.Collections;
22 import java.util.Iterator;
23
24 import org.junit.Test;
25
26 import org.springframework.cache.annotation.AnnotationCacheOperationSource;
27 import org.springframework.cache.annotation.Cacheable;
28 import org.springframework.cache.annotation.Caching;
29 import org.springframework.cache.concurrent.ConcurrentMapCache;
30 import org.springframework.expression.EvaluationContext;
31 import org.springframework.expression.spel.standard.SpelExpressionParser;
32 import org.springframework.util.ReflectionUtils;
33
34 import static org.hamcrest.Matchers.*;
35 import static org.junit.Assert.*;
36
37
38
39
40
41
42
43 public class ExpressionEvaluatorTests {
44
45 private ExpressionEvaluator eval = new ExpressionEvaluator();
46
47 private AnnotationCacheOperationSource source = new AnnotationCacheOperationSource();
48
49 private Collection<CacheOperation> getOps(String name) {
50 Method method = ReflectionUtils.findMethod(AnnotatedClass.class, name, Object.class, Object.class);
51 return source.getCacheOperations(method, AnnotatedClass.class);
52 }
53
54 @Test
55 public void testMultipleCachingSource() throws Exception {
56 Collection<CacheOperation> ops = getOps("multipleCaching");
57 assertEquals(2, ops.size());
58 Iterator<CacheOperation> it = ops.iterator();
59 CacheOperation next = it.next();
60 assertTrue(next instanceof CacheableOperation);
61 assertTrue(next.getCacheNames().contains("test"));
62 assertEquals("#a", next.getKey());
63 next = it.next();
64 assertTrue(next instanceof CacheableOperation);
65 assertTrue(next.getCacheNames().contains("test"));
66 assertEquals("#b", next.getKey());
67 }
68
69 @Test
70 public void testMultipleCachingEval() throws Exception {
71 AnnotatedClass target = new AnnotatedClass();
72 Method method = ReflectionUtils.findMethod(AnnotatedClass.class, "multipleCaching", Object.class,
73 Object.class);
74 Object[] args = new Object[] { new Object(), new Object() };
75 Collection<ConcurrentMapCache> caches = Collections.singleton(new ConcurrentMapCache("test"));
76
77 EvaluationContext evalCtx = eval.createEvaluationContext(caches, method, args, target, target.getClass());
78 Collection<CacheOperation> ops = getOps("multipleCaching");
79
80 Iterator<CacheOperation> it = ops.iterator();
81
82 MethodCacheKey key = new MethodCacheKey(method, AnnotatedClass.class);
83
84 Object keyA = eval.key(it.next().getKey(), key, evalCtx);
85 Object keyB = eval.key(it.next().getKey(), key, evalCtx);
86
87 assertEquals(args[0], keyA);
88 assertEquals(args[1], keyB);
89 }
90
91 @Test
92 public void withReturnValue() throws Exception {
93 EvaluationContext context = createEvaluationContext("theResult");
94 Object value = new SpelExpressionParser().parseExpression("#result").getValue(context);
95 assertThat(value, equalTo((Object) "theResult"));
96 }
97
98 @Test
99 public void withNullReturn() throws Exception {
100 EvaluationContext context = createEvaluationContext(null);
101 Object value = new SpelExpressionParser().parseExpression("#result").getValue(context);
102 assertThat(value, nullValue());
103 }
104
105 @Test
106 public void withoutReturnValue() throws Exception {
107 EvaluationContext context = createEvaluationContext(ExpressionEvaluator.NO_RESULT);
108 Object value = new SpelExpressionParser().parseExpression("#result").getValue(context);
109 assertThat(value, nullValue());
110 }
111
112 @Test
113 public void unavailableReturnValue() throws Exception {
114 EvaluationContext context = createEvaluationContext(ExpressionEvaluator.RESULT_UNAVAILABLE);
115 try {
116 new SpelExpressionParser().parseExpression("#result").getValue(context);
117 fail("Should have failed to parse expression, result not available");
118 }
119 catch (VariableNotAvailableException e) {
120 assertEquals("wrong variable name", "result", e.getName());
121 }
122 }
123
124 private EvaluationContext createEvaluationContext(Object result) {
125 AnnotatedClass target = new AnnotatedClass();
126 Method method = ReflectionUtils.findMethod(AnnotatedClass.class, "multipleCaching", Object.class,
127 Object.class);
128 Object[] args = new Object[] { new Object(), new Object() };
129 Collection<ConcurrentMapCache> caches = Collections.singleton(new ConcurrentMapCache("test"));
130 EvaluationContext context = eval.createEvaluationContext(caches, method, args, target, target.getClass(), result);
131 return context;
132 }
133
134
135 private static class AnnotatedClass {
136
137 @Caching(cacheable = { @Cacheable(value = "test", key = "#a"), @Cacheable(value = "test", key = "#b") })
138 public void multipleCaching(Object a, Object b) {
139 }
140 }
141
142 }