aboutsummaryrefslogtreecommitdiff
path: root/src/test/java/com/android/volley/CacheDispatcherTest.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/java/com/android/volley/CacheDispatcherTest.java')
-rw-r--r--src/test/java/com/android/volley/CacheDispatcherTest.java254
1 files changed, 145 insertions, 109 deletions
diff --git a/src/test/java/com/android/volley/CacheDispatcherTest.java b/src/test/java/com/android/volley/CacheDispatcherTest.java
index a39be7b..9c5d3c3 100644
--- a/src/test/java/com/android/volley/CacheDispatcherTest.java
+++ b/src/test/java/com/android/volley/CacheDispatcherTest.java
@@ -16,183 +16,219 @@
package com.android.volley;
-import com.android.volley.mock.MockCache;
-import com.android.volley.mock.MockRequest;
-import com.android.volley.mock.MockResponseDelivery;
-import com.android.volley.mock.WaitableQueue;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import static org.mockito.MockitoAnnotations.initMocks;
+
+import com.android.volley.toolbox.StringRequest;
import com.android.volley.utils.CacheTestUtils;
-
-import org.junit.After;
+import java.util.concurrent.BlockingQueue;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
import org.robolectric.RobolectricTestRunner;
-import static org.junit.Assert.*;
-
@RunWith(RobolectricTestRunner.class)
@SuppressWarnings("rawtypes")
public class CacheDispatcherTest {
private CacheDispatcher mDispatcher;
- private WaitableQueue mCacheQueue;
- private WaitableQueue mNetworkQueue;
- private MockCache mCache;
- private MockResponseDelivery mDelivery;
- private MockRequest mRequest;
+ private @Mock BlockingQueue<Request<?>> mCacheQueue;
+ private @Mock BlockingQueue<Request<?>> mNetworkQueue;
+ private @Mock Cache mCache;
+ private @Mock ResponseDelivery mDelivery;
+ private StringRequest mRequest;
- private static final long TIMEOUT_MILLIS = 5000;
+ @Before
+ public void setUp() throws Exception {
+ initMocks(this);
- @Before public void setUp() throws Exception {
- mCacheQueue = new WaitableQueue();
- mNetworkQueue = new WaitableQueue();
- mCache = new MockCache();
- mDelivery = new MockResponseDelivery();
+ mRequest = new StringRequest(Request.Method.GET, "http://foo", null, null);
+ mDispatcher = new CacheDispatcher(mCacheQueue, mNetworkQueue, mCache, mDelivery);
+ }
- mRequest = new MockRequest();
+ private static class WaitForever implements Answer {
+ @Override
+ public Object answer(InvocationOnMock invocationOnMock) throws Throwable {
+ Thread.sleep(Long.MAX_VALUE);
+ return null;
+ }
+ }
- mDispatcher = new CacheDispatcher(mCacheQueue, mNetworkQueue, mCache, mDelivery);
+ @Test
+ public void runStopsOnQuit() throws Exception {
+ when(mCacheQueue.take()).then(new WaitForever());
mDispatcher.start();
+ mDispatcher.quit();
+ mDispatcher.join(1000);
}
- @After public void tearDown() throws Exception {
- mDispatcher.quit();
- mDispatcher.join();
+ private static void verifyNoResponse(ResponseDelivery delivery) {
+ verify(delivery, never()).postResponse(any(Request.class), any(Response.class));
+ verify(delivery, never())
+ .postResponse(any(Request.class), any(Response.class), any(Runnable.class));
+ verify(delivery, never()).postError(any(Request.class), any(VolleyError.class));
}
// A cancelled request should not be processed at all.
- @Test public void cancelledRequest() throws Exception {
+ @Test
+ public void cancelledRequest() throws Exception {
mRequest.cancel();
- mCacheQueue.add(mRequest);
- mCacheQueue.waitUntilEmpty(TIMEOUT_MILLIS);
- assertFalse(mCache.getCalled);
- assertFalse(mDelivery.wasEitherResponseCalled());
+ mDispatcher.processRequest(mRequest);
+ verify(mCache, never()).get(anyString());
+ verifyNoResponse(mDelivery);
}
// A cache miss does not post a response and puts the request on the network queue.
- @Test public void cacheMiss() throws Exception {
- mCacheQueue.add(mRequest);
- mCacheQueue.waitUntilEmpty(TIMEOUT_MILLIS);
- assertFalse(mDelivery.wasEitherResponseCalled());
- assertTrue(mNetworkQueue.size() > 0);
- Request request = mNetworkQueue.take();
- assertNull(request.getCacheEntry());
+ @Test
+ public void cacheMiss() throws Exception {
+ mDispatcher.processRequest(mRequest);
+ verifyNoResponse(mDelivery);
+ verify(mNetworkQueue).put(mRequest);
+ assertNull(mRequest.getCacheEntry());
}
// A non-expired cache hit posts a response and does not queue to the network.
- @Test public void nonExpiredCacheHit() throws Exception {
+ @Test
+ public void nonExpiredCacheHit() throws Exception {
Cache.Entry entry = CacheTestUtils.makeRandomCacheEntry(null, false, false);
- mCache.setEntryToReturn(entry);
- mCacheQueue.add(mRequest);
- mCacheQueue.waitUntilEmpty(TIMEOUT_MILLIS);
- assertTrue(mDelivery.postResponse_called);
- assertFalse(mDelivery.postError_called);
+ when(mCache.get(anyString())).thenReturn(entry);
+ mDispatcher.processRequest(mRequest);
+ verify(mDelivery).postResponse(any(Request.class), any(Response.class));
+ verify(mDelivery, never()).postError(any(Request.class), any(VolleyError.class));
}
// A soft-expired cache hit posts a response and queues to the network.
- @Test public void softExpiredCacheHit() throws Exception {
+ @Test
+ public void softExpiredCacheHit() throws Exception {
Cache.Entry entry = CacheTestUtils.makeRandomCacheEntry(null, false, true);
- mCache.setEntryToReturn(entry);
- mCacheQueue.add(mRequest);
- mCacheQueue.waitUntilEmpty(TIMEOUT_MILLIS);
- assertTrue(mDelivery.postResponse_called);
- assertFalse(mDelivery.postError_called);
- assertTrue(mNetworkQueue.size() > 0);
- Request request = mNetworkQueue.take();
- assertSame(entry, request.getCacheEntry());
+ when(mCache.get(anyString())).thenReturn(entry);
+ mDispatcher.processRequest(mRequest);
+
+ // Soft expiration needs to use the deferred Runnable variant of postResponse,
+ // so make sure it gets to run.
+ ArgumentCaptor<Runnable> runnable = ArgumentCaptor.forClass(Runnable.class);
+ verify(mDelivery).postResponse(any(Request.class), any(Response.class), runnable.capture());
+ runnable.getValue().run();
+ // This way we can verify the behavior of the Runnable as well.
+ verify(mNetworkQueue).put(mRequest);
+ assertSame(entry, mRequest.getCacheEntry());
+
+ verify(mDelivery, never()).postError(any(Request.class), any(VolleyError.class));
}
// An expired cache hit does not post a response and queues to the network.
- @Test public void expiredCacheHit() throws Exception {
+ @Test
+ public void expiredCacheHit() throws Exception {
Cache.Entry entry = CacheTestUtils.makeRandomCacheEntry(null, true, true);
- mCache.setEntryToReturn(entry);
- mCacheQueue.add(mRequest);
- mCacheQueue.waitUntilEmpty(TIMEOUT_MILLIS);
- assertFalse(mDelivery.wasEitherResponseCalled());
- assertTrue(mNetworkQueue.size() > 0);
- Request request = mNetworkQueue.take();
- assertSame(entry, request.getCacheEntry());
+ when(mCache.get(anyString())).thenReturn(entry);
+ mDispatcher.processRequest(mRequest);
+ verifyNoResponse(mDelivery);
+ verify(mNetworkQueue).put(mRequest);
+ assertSame(entry, mRequest.getCacheEntry());
}
- @Test public void duplicateCacheMiss() throws Exception {
- MockRequest secondRequest = new MockRequest();
+ @Test
+ public void duplicateCacheMiss() throws Exception {
+ StringRequest secondRequest =
+ new StringRequest(Request.Method.GET, "http://foo", null, null);
mRequest.setSequence(1);
secondRequest.setSequence(2);
- mCacheQueue.add(mRequest);
- mCacheQueue.add(secondRequest);
- mCacheQueue.waitUntilEmpty(TIMEOUT_MILLIS);
- assertTrue(mNetworkQueue.size() == 1);
- assertFalse(mDelivery.postResponse_called);
+ mDispatcher.processRequest(mRequest);
+ mDispatcher.processRequest(secondRequest);
+ verify(mNetworkQueue).put(mRequest);
+ verifyNoResponse(mDelivery);
}
- @Test public void tripleCacheMiss_networkErrorOnFirst() throws Exception {
- MockRequest secondRequest = new MockRequest();
- MockRequest thirdRequest = new MockRequest();
+ @Test
+ public void tripleCacheMiss_networkErrorOnFirst() throws Exception {
+ StringRequest secondRequest =
+ new StringRequest(Request.Method.GET, "http://foo", null, null);
+ StringRequest thirdRequest =
+ new StringRequest(Request.Method.GET, "http://foo", null, null);
mRequest.setSequence(1);
secondRequest.setSequence(2);
thirdRequest.setSequence(3);
- mCacheQueue.add(mRequest);
- mCacheQueue.add(secondRequest);
- mCacheQueue.add(thirdRequest);
- mCacheQueue.waitUntilEmpty(TIMEOUT_MILLIS);
+ mDispatcher.processRequest(mRequest);
+ mDispatcher.processRequest(secondRequest);
+ mDispatcher.processRequest(thirdRequest);
- assertTrue(mNetworkQueue.size() == 1);
- assertFalse(mDelivery.postResponse_called);
+ verify(mNetworkQueue).put(mRequest);
+ verifyNoResponse(mDelivery);
- Request request = mNetworkQueue.take();
- request.notifyListenerResponseNotUsable();
+ ((Request<?>) mRequest).notifyListenerResponseNotUsable();
// Second request should now be in network queue.
- assertTrue(mNetworkQueue.size() == 1);
- request = mNetworkQueue.take();
- assertTrue(request.equals(secondRequest));
+ verify(mNetworkQueue).put(secondRequest);
// Another unusable response, third request should now be added.
- request.notifyListenerResponseNotUsable();
- assertTrue(mNetworkQueue.size() == 1);
- request = mNetworkQueue.take();
- assertTrue(request.equals(thirdRequest));
+ ((Request<?>) secondRequest).notifyListenerResponseNotUsable();
+ verify(mNetworkQueue).put(thirdRequest);
}
- @Test public void duplicateSoftExpiredCacheHit_failedRequest() throws Exception {
+ @Test
+ public void duplicateSoftExpiredCacheHit_failedRequest() throws Exception {
Cache.Entry entry = CacheTestUtils.makeRandomCacheEntry(null, false, true);
- mCache.setEntryToReturn(entry);
+ when(mCache.get(anyString())).thenReturn(entry);
- MockRequest secondRequest = new MockRequest();
+ StringRequest secondRequest =
+ new StringRequest(Request.Method.GET, "http://foo", null, null);
mRequest.setSequence(1);
secondRequest.setSequence(2);
- mCacheQueue.add(mRequest);
- mCacheQueue.add(secondRequest);
- mCacheQueue.waitUntilEmpty(TIMEOUT_MILLIS);
+ mDispatcher.processRequest(mRequest);
+ mDispatcher.processRequest(secondRequest);
- assertTrue(mNetworkQueue.size() == 1);
- assertTrue(mDelivery.postResponse_calledNtimes == 2);
+ // Soft expiration needs to use the deferred Runnable variant of postResponse,
+ // so make sure it gets to run.
+ ArgumentCaptor<Runnable> runnable = ArgumentCaptor.forClass(Runnable.class);
+ verify(mDelivery).postResponse(any(Request.class), any(Response.class), runnable.capture());
+ runnable.getValue().run();
+ // This way we can verify the behavior of the Runnable as well.
- Request request = mNetworkQueue.take();
- request.notifyListenerResponseNotUsable();
+ verify(mNetworkQueue).put(mRequest);
+ verify(mDelivery)
+ .postResponse(any(Request.class), any(Response.class), any(Runnable.class));
+
+ ((Request<?>) mRequest).notifyListenerResponseNotUsable();
// Second request should now be in network queue.
- assertTrue(mNetworkQueue.size() == 1);
- request = mNetworkQueue.take();
- assertTrue(request.equals(secondRequest));
+ verify(mNetworkQueue).put(secondRequest);
}
- @Test public void duplicateSoftExpiredCacheHit_successfulRequest() throws Exception {
+ @Test
+ public void duplicateSoftExpiredCacheHit_successfulRequest() throws Exception {
Cache.Entry entry = CacheTestUtils.makeRandomCacheEntry(null, false, true);
- mCache.setEntryToReturn(entry);
+ when(mCache.get(anyString())).thenReturn(entry);
- MockRequest secondRequest = new MockRequest();
+ StringRequest secondRequest =
+ new StringRequest(Request.Method.GET, "http://foo", null, null);
mRequest.setSequence(1);
secondRequest.setSequence(2);
- mCacheQueue.add(mRequest);
- mCacheQueue.add(secondRequest);
- mCacheQueue.waitUntilEmpty(TIMEOUT_MILLIS);
+ mDispatcher.processRequest(mRequest);
+ mDispatcher.processRequest(secondRequest);
+
+ // Soft expiration needs to use the deferred Runnable variant of postResponse,
+ // so make sure it gets to run.
+ ArgumentCaptor<Runnable> runnable = ArgumentCaptor.forClass(Runnable.class);
+ verify(mDelivery).postResponse(any(Request.class), any(Response.class), runnable.capture());
+ runnable.getValue().run();
+ // This way we can verify the behavior of the Runnable as well.
- assertTrue(mNetworkQueue.size() == 1);
- assertTrue(mDelivery.postResponse_calledNtimes == 2);
+ verify(mNetworkQueue).put(mRequest);
+ verify(mDelivery)
+ .postResponse(any(Request.class), any(Response.class), any(Runnable.class));
- Request request = mNetworkQueue.take();
- request.notifyListenerResponseReceived(Response.success(null, entry));
+ ((Request<?>) mRequest).notifyListenerResponseReceived(Response.success(null, entry));
// Second request should have delivered response.
- assertTrue(mNetworkQueue.size() == 0);
- assertTrue(mDelivery.postResponse_calledNtimes == 3);
+ verify(mNetworkQueue, never()).put(secondRequest);
+ verify(mDelivery)
+ .postResponse(any(Request.class), any(Response.class), any(Runnable.class));
}
}