Skip to content

Commit 750c381

Browse files
committed
Added test to RxJava Observables
1 parent b104753 commit 750c381

File tree

3 files changed

+280
-3
lines changed

3 files changed

+280
-3
lines changed

spring-context/src/main/java/org/springframework/cache/interceptor/CacheAspectSupport.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -387,9 +387,10 @@ public Object call() throws Exception {
387387
// TODO: cacheValue = ObjectUtils.unwrapOptional(returnValue); use this to wrap/unwrap
388388

389389
// Invoke the method if we don't have a cache hit
390-
returnValue = invokeOperation(invoker);
390+
Object originalReturnValue = invokeOperation(invoker);
391391

392-
cacheResultWrapperManager.asyncUnwrap(returnValue, new AsyncWrapResult(new AsyncWrapResult.CallBack() {
392+
returnValue = cacheResultWrapperManager.asyncUnwrap(originalReturnValue, new
393+
AsyncWrapResult(new AsyncWrapResult.CallBack() {
393394
@Override
394395
public void onValue(Object cacheValue) {
395396
updateCache(cacheValue, contexts, cachePutRequests);

spring-context/src/main/java/org/springframework/cache/interceptor/CacheResultWrapperManager.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@ public Object wrap(Class<?> clazz, Object value) {
4949
}
5050

5151
public Object asyncUnwrap(Object valueWrapped, AsyncWrapResult asyncResult) {
52-
System.out.println("valueWrapped = " + valueWrapped);
5352
if(valueWrapped != null) {
5453
CacheResultWrapper unwrapper = unwrapperByClass.get(valueWrapped.getClass());
5554

Lines changed: 277 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,277 @@
1+
/*
2+
* Copyright 2002-2016 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.cache;
18+
19+
import org.junit.Before;
20+
import org.junit.Test;
21+
import org.springframework.cache.annotation.Cacheable;
22+
import org.springframework.cache.annotation.EnableCaching;
23+
import org.springframework.cache.concurrent.ConcurrentMapCacheManager;
24+
import org.springframework.cache.interceptor.SimpleKey;
25+
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
26+
import org.springframework.context.annotation.Bean;
27+
import org.springframework.context.annotation.Configuration;
28+
29+
import java.util.List;
30+
import java.util.concurrent.Callable;
31+
32+
import rx.Observable;
33+
import rx.functions.Func0;
34+
import rx.observers.TestSubscriber;
35+
36+
import static org.junit.Assert.assertEquals;
37+
import static org.junit.Assert.assertNotSame;
38+
import static org.junit.Assert.assertNull;
39+
40+
/**
41+
* Tests to check RxJava support.
42+
*
43+
* @author Pablo Diaz
44+
*/
45+
public class CacheRxJavaTests {
46+
private AnnotationConfigApplicationContext context;
47+
private TestService bean;
48+
49+
@Before
50+
public void before() {
51+
context = new AnnotationConfigApplicationContext(BasicTestConfig.class);
52+
bean = context.getBean(TestService.class);
53+
}
54+
55+
@Test
56+
public void single() {
57+
Cache cache = context.getBean(CacheManager.class).getCache("single");
58+
Observable<Object> single = bean.single();
59+
TestSubscriber<Object> testSubscriber = new TestSubscriber<Object>();
60+
61+
single.subscribe(testSubscriber);
62+
testSubscriber.awaitTerminalEvent();
63+
64+
Object cachedValues = cache.get(SimpleKey.EMPTY).get();
65+
List<Object> resultValues = testSubscriber.getOnNextEvents();
66+
67+
assertNotSame(cachedValues, resultValues);
68+
assertEquals(cachedValues, resultValues);
69+
}
70+
71+
@Test
72+
public void multiple() {
73+
Cache cache = context.getBean(CacheManager.class).getCache("multiple");
74+
Observable<Object> multiple = bean.multiple();
75+
TestSubscriber<Object> testSubscriber = new TestSubscriber<Object>();
76+
77+
multiple.subscribe(testSubscriber);
78+
testSubscriber.awaitTerminalEvent();
79+
80+
Object cachedValues = cache.get(SimpleKey.EMPTY).get();
81+
List<Object> resultValues = testSubscriber.getOnNextEvents();
82+
83+
assertNotSame(cachedValues, resultValues);
84+
assertEquals(cachedValues, resultValues);
85+
}
86+
87+
@Test
88+
public void empty() {
89+
Cache cache = context.getBean(CacheManager.class).getCache("empty");
90+
Observable<Object> empty = bean.empty();
91+
TestSubscriber<Object> testSubscriber = new TestSubscriber<Object>();
92+
93+
empty.subscribe(testSubscriber);
94+
testSubscriber.awaitTerminalEvent();
95+
96+
Object cachedValues = cache.get(SimpleKey.EMPTY).get();
97+
List<Object> resultValues = testSubscriber.getOnNextEvents();
98+
99+
assertNotSame(cachedValues, resultValues);
100+
assertEquals(cachedValues, resultValues);
101+
}
102+
103+
@Test
104+
public void nullValue() {
105+
Cache cache = context.getBean(CacheManager.class).getCache("nullValue");
106+
Observable<Object> nullValue = bean.nullValue();
107+
TestSubscriber<Object> testSubscriber = new TestSubscriber<Object>();
108+
109+
nullValue.subscribe(testSubscriber);
110+
testSubscriber.awaitTerminalEvent();
111+
112+
Object cachedValues = cache.get(SimpleKey.EMPTY).get();
113+
List<Object> resultValues = testSubscriber.getOnNextEvents();
114+
115+
assertNotSame(cachedValues, resultValues);
116+
assertEquals(cachedValues, resultValues);
117+
}
118+
119+
@Test
120+
public void nullObservable() {
121+
Cache cache = context.getBean(CacheManager.class).getCache("nullObservable");
122+
Observable<Object> nullObservable = bean.nullObservable();
123+
124+
Object cachedValues = cache.get(SimpleKey.EMPTY).get();
125+
126+
assertNull("Value is cached as null", cachedValues);
127+
}
128+
129+
@Test
130+
public void throwable() {
131+
Cache cache = context.getBean(CacheManager.class).getCache("throwable");
132+
Observable<Object> throwable = bean.nullValue();
133+
TestSubscriber<Object> testSubscriber = new TestSubscriber<Object>();
134+
135+
throwable.subscribe(testSubscriber);
136+
testSubscriber.awaitTerminalEvent();
137+
138+
Cache.ValueWrapper valueWrapper = cache.get(SimpleKey.EMPTY);
139+
140+
assertNull(valueWrapper);
141+
}
142+
143+
@Test
144+
public void partialReturnAndError() {
145+
Cache cache = context.getBean(CacheManager.class).getCache("partialReturnAndError");
146+
Observable<Object> partialReturnAndError = bean.partialReturnAndError();
147+
TestSubscriber<Object> testSubscriber = new TestSubscriber<Object>();
148+
149+
partialReturnAndError.subscribe(testSubscriber);
150+
testSubscriber.awaitTerminalEvent();
151+
152+
Cache.ValueWrapper valueWrapper = cache.get(SimpleKey.EMPTY);
153+
154+
assertNull(valueWrapper);
155+
156+
}
157+
158+
@Test(timeout = 1000L)
159+
public void neverFinish() {
160+
Cache cache = context.getBean(CacheManager.class).getCache("neverFinish");
161+
bean.neverFinish();
162+
163+
Cache.ValueWrapper valueWrapper = cache.get(SimpleKey.EMPTY);
164+
165+
assertNull(valueWrapper);
166+
}
167+
168+
@Configuration
169+
@EnableCaching
170+
public static class BasicTestConfig {
171+
172+
@Bean
173+
public CacheManager cacheManager() {
174+
return new ConcurrentMapCacheManager();
175+
}
176+
177+
@Bean
178+
public TestService service() {
179+
return new TestServiceImpl();
180+
}
181+
}
182+
183+
184+
public interface TestService {
185+
Observable<Object> single();
186+
187+
Observable<Object> multiple();
188+
189+
Observable<Object> empty();
190+
191+
Observable<Object> nullValue();
192+
193+
Observable<Object> nullObservable();
194+
195+
Observable<Object> throwable();
196+
197+
Observable<Object> partialReturnAndError();
198+
199+
Observable<Object> neverFinish();
200+
201+
}
202+
203+
204+
public static class TestServiceImpl implements TestService {
205+
@Cacheable("single")
206+
@Override
207+
public Observable<Object> single() {
208+
return createObservable(new TestBean(1));
209+
}
210+
211+
@Cacheable("multiple")
212+
@Override
213+
public Observable<Object> multiple() {
214+
return createObservable(new TestBean(1), new TestBean(2));
215+
}
216+
217+
@Cacheable("empty")
218+
@Override
219+
public Observable<Object> empty() {
220+
return Observable.empty();
221+
}
222+
223+
@Cacheable("nullValue")
224+
@Override
225+
public Observable<Object> nullValue() {
226+
return createObservable((Object)null);
227+
}
228+
229+
@Cacheable("nullObservable")
230+
@Override
231+
public Observable<Object> nullObservable() {
232+
return null;
233+
}
234+
235+
@Cacheable("throwable")
236+
@Override
237+
public Observable<Object> throwable() {
238+
return Observable.fromCallable(new Callable<Object>() {
239+
@Override
240+
public Object call() throws Exception {
241+
throw new RuntimeException();
242+
}
243+
});
244+
}
245+
246+
@Cacheable("partialReturnAndError")
247+
@Override
248+
public Observable<Object> partialReturnAndError() {
249+
return createObservable(new TestBean(1), new TestBean(2))
250+
.concatWith(Observable.error(new RuntimeException()));
251+
}
252+
253+
@Cacheable("neverFinish")
254+
@Override
255+
public Observable<Object> neverFinish() {
256+
return Observable.never();
257+
}
258+
259+
private Observable<Object> createObservable(Object... values) {
260+
return Observable.defer(new Func0<Observable<Object>>() {
261+
@Override
262+
public Observable<Object> call() {
263+
return Observable.from(values);
264+
}
265+
});
266+
}
267+
}
268+
269+
270+
static class TestBean {
271+
private Integer value;
272+
273+
public TestBean(Integer value) {
274+
this.value = value;
275+
}
276+
}
277+
}

0 commit comments

Comments
 (0)