2 * Copyright 2005-2010 the original author or authors.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 package org.wamblee.cache;
18 import static org.mockito.Mockito.*;
20 import java.util.ArrayList;
21 import java.util.List;
23 import junit.framework.TestCase;
25 import org.mockito.invocation.InvocationOnMock;
26 import org.mockito.stubbing.Answer;
27 import org.wamblee.cache.ComputedValue.Computation;
29 public class ComputedValueTest extends TestCase {
31 private Computation<Integer> computation;
32 private ComputedValue<Integer> guard;
35 protected void setUp() throws Exception {
36 computation = mock(Computation.class);
39 public void testComputeOutOfDate() {
43 private void initGuard() {
44 guard = new ComputedValue<Integer>(this, computation);
46 assertNull(guard.getCached());
48 when(computation.isOutOfDate()).thenReturn(true);
49 when(computation.compute()).thenReturn(10);
51 int value = guard.get();
52 assertEquals(10, value);
53 verify(computation).compute();
57 public void testGetCached() {
59 assertEquals(10, (int) guard.getCached());
60 verifyNoMoreInteractions(computation);
63 public void testNoComputationWhenNotOutOfDate() {
65 when(computation.isOutOfDate()).thenReturn(false);
66 assertEquals(10, (int) guard.get());
67 verify(computation, never()).compute();
70 public void testOnlyOneConcurrentComputation() throws Exception {
72 final int computeTime = 500;
73 when(computation.isOutOfDate()).thenReturn(true);
74 when(computation.compute()).thenAnswer(new Answer<Integer>() {
76 public Integer answer(InvocationOnMock aInvocation)
78 Thread.sleep(computeTime);
83 final List<Integer> results = new ArrayList<Integer>();
85 Runnable task = new Runnable() {
88 int res = guard.get();
93 // concurrent computation in two threads.
94 Thread t1 = new Thread(task);
95 Thread t2 = new Thread(task);
97 Thread.sleep(computeTime / 2);
98 // second task will return old value 10 because first one is still busy.
102 assertEquals(2, results.size());
103 assertEquals(10, (int) results.get(0));
104 assertEquals(100, (int) results.get(1));
105 verify(computation, times(2)).isOutOfDate();
108 public void testExceptionWhileComputing() {
110 when(computation.isOutOfDate()).thenReturn(true);
111 when(computation.compute()).thenThrow(new RuntimeException("xx"));
115 } catch (RuntimeException e) {
116 assertEquals("xx", e.getMessage());
120 public void testExceptionWhileCheckingOutOfDate() {
122 when(computation.isOutOfDate()).thenThrow(new RuntimeException("xx"));
126 } catch (RuntimeException e) {
127 assertEquals("xx", e.getMessage());