diff --git a/pom.xml b/pom.xml index 57e297bc9feaa94f690e79b1fd13915b38b23b38..35659617b513523fa2caf54c98f39d8b6a34106f 100644 --- a/pom.xml +++ b/pom.xml @@ -75,7 +75,6 @@ 4.12 1.7.0 - 1.9.5 3.8 @@ -195,11 +194,6 @@ assertj-core ${assertj.version} - - org.mockito - mockito-core - ${mockito.version} - com.google.guava guava diff --git a/retrofit-mock/pom.xml b/retrofit-mock/pom.xml index 1c943c326f8c76b5577fd34a894a06702cb5f4da..570a670068e84faa28e5a9c312ded5602565294d 100644 --- a/retrofit-mock/pom.xml +++ b/retrofit-mock/pom.xml @@ -35,11 +35,6 @@ assertj-core test - - org.mockito - mockito-core - test - diff --git a/retrofit/pom.xml b/retrofit/pom.xml index 16808f39938509cd3ba6857f2ae805a00cdd48fb..7eccd97d59a67d2a3b46906441b41f46cfd096e8 100644 --- a/retrofit/pom.xml +++ b/retrofit/pom.xml @@ -56,11 +56,6 @@ assertj-core test - - org.mockito - mockito-core - test - com.google.guava guava diff --git a/retrofit/src/test/java/retrofit2/CallTest.java b/retrofit/src/test/java/retrofit2/CallTest.java index 4f579034f5e811f2c3feda83b9a8d73c5a84107a..a99bf3646d05e75f9bd94586e406383fc27fb85a 100644 --- a/retrofit/src/test/java/retrofit2/CallTest.java +++ b/retrofit/src/test/java/retrofit2/CallTest.java @@ -47,8 +47,6 @@ import static okhttp3.mockwebserver.SocketPolicy.DISCONNECT_DURING_RESPONSE_BODY import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.verifyNoMoreInteractions; import static retrofit2.TestingUtils.repeat; public final class CallTest { @@ -371,11 +369,11 @@ public final class CallTest { } @Test public void http204SkipsConverter() throws IOException { - final Converter converter = spy(new Converter() { - @Override public String convert(ResponseBody value) throws IOException { - return value.string(); + final Converter converter = new Converter() { + @Override public String convert(ResponseBody value) { + throw new AssertionError(); } - }); + }; Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new ToStringConverterFactory() { @@ -393,15 +391,14 @@ public final class CallTest { Response response = example.getString().execute(); assertThat(response.code()).isEqualTo(204); assertThat(response.body()).isNull(); - verifyNoMoreInteractions(converter); } @Test public void http205SkipsConverter() throws IOException { - final Converter converter = spy(new Converter() { - @Override public String convert(ResponseBody value) throws IOException { - return value.string(); + final Converter converter = new Converter() { + @Override public String convert(ResponseBody value) { + throw new AssertionError(); } - }); + }; Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new ToStringConverterFactory() { @@ -419,7 +416,6 @@ public final class CallTest { Response response = example.getString().execute(); assertThat(response.code()).isEqualTo(205); assertThat(response.body()).isNull(); - verifyNoMoreInteractions(converter); } @Test public void converterBodyDoesNotLeakContentInIntermediateBuffers() throws IOException { diff --git a/retrofit/src/test/java/retrofit2/DefaultCallAdapterFactoryTest.java b/retrofit/src/test/java/retrofit2/DefaultCallAdapterFactoryTest.java index 9a40ca5f13f4292c03287b6f939d0abb82b0232b..e23a5d3c1aa325788141d2e6432e1957fe01872c 100644 --- a/retrofit/src/test/java/retrofit2/DefaultCallAdapterFactoryTest.java +++ b/retrofit/src/test/java/retrofit2/DefaultCallAdapterFactoryTest.java @@ -21,16 +21,14 @@ import java.lang.annotation.Annotation; import java.lang.reflect.Type; import java.util.List; import java.util.concurrent.Executor; +import java.util.concurrent.atomic.AtomicBoolean; import okhttp3.Request; +import org.jetbrains.annotations.NotNull; import org.junit.Test; import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; @SuppressWarnings("unchecked") public final class DefaultCallAdapterFactoryTest { @@ -39,13 +37,11 @@ public final class DefaultCallAdapterFactoryTest { private final Retrofit retrofit = new Retrofit.Builder() .baseUrl("http://localhost:1") .build(); - private final Callback callback = mock(Callback.class); - private final Executor callbackExecutor = spy(new Executor() { - @Override public void execute(Runnable runnable) { - runnable.run(); + private final CallAdapter.Factory factory = new DefaultCallAdapterFactory(new Executor() { + @Override public void execute(@NotNull Runnable command) { + command.run(); } }); - private final CallAdapter.Factory factory = new DefaultCallAdapterFactory(callbackExecutor); @Test public void rawTypeThrows() { try { @@ -74,68 +70,42 @@ public final class DefaultCallAdapterFactoryTest { (CallAdapter>) factory.get(returnType, NO_ANNOTATIONS, retrofit); final Response response = Response.success("Hi"); Call call = adapter.adapt(new EmptyCall() { - @Override public Response execute() throws IOException { + @Override public Response execute() { return response; } }); assertThat(call.execute()).isSameAs(response); } - @Test public void adaptedCallEnqueueUsesExecutorForSuccessCallback() { - Type returnType = new TypeToken>() {}.getType(); - CallAdapter> adapter = - (CallAdapter>) factory.get(returnType, NO_ANNOTATIONS, retrofit); - final Response response = Response.success("Hi"); - EmptyCall originalCall = new EmptyCall() { - @Override public void enqueue(Callback callback) { - callback.onResponse(this, response); - } - }; - Call call = adapter.adapt(originalCall); - call.enqueue(callback); - verify(callbackExecutor).execute(any(Runnable.class)); - verify(callback).onResponse(call, response); - } - - @Test public void adaptedCallEnqueueUsesExecutorForFailureCallback() { + @Test public void adaptedCallCloneDeepCopy() { Type returnType = new TypeToken>() {}.getType(); CallAdapter> adapter = (CallAdapter>) factory.get(returnType, NO_ANNOTATIONS, retrofit); - final Throwable throwable = new IOException(); - EmptyCall originalCall = new EmptyCall() { - @Override public void enqueue(Callback callback) { - callback.onFailure(this, throwable); + final AtomicBoolean cloned = new AtomicBoolean(); + Call delegate = new EmptyCall() { + @Override public Call clone() { + cloned.set(true); + return this; } }; - Call call = adapter.adapt(originalCall); - call.enqueue(callback); - verify(callbackExecutor).execute(any(Runnable.class)); - verifyNoMoreInteractions(callbackExecutor); - verify(callback).onFailure(call, throwable); - verifyNoMoreInteractions(callback); - } - - @Test public void adaptedCallCloneDeepCopy() { - Type returnType = new TypeToken>() {}.getType(); - CallAdapter> adapter = - (CallAdapter>) factory.get(returnType, NO_ANNOTATIONS, retrofit); - Call delegate = mock(Call.class); Call call = adapter.adapt(delegate); - Call cloned = call.clone(); - assertThat(cloned).isNotSameAs(call); - verify(delegate).clone(); - verifyNoMoreInteractions(delegate); + assertThat(call.clone()).isNotSameAs(call); + assertTrue(cloned.get()); } @Test public void adaptedCallCancel() { Type returnType = new TypeToken>() {}.getType(); CallAdapter> adapter = (CallAdapter>) factory.get(returnType, NO_ANNOTATIONS, retrofit); - Call delegate = mock(Call.class); + final AtomicBoolean canceled = new AtomicBoolean(); + Call delegate = new EmptyCall() { + @Override public void cancel() { + canceled.set(true); + } + }; Call call = adapter.adapt(delegate); call.cancel(); - verify(delegate).cancel(); - verifyNoMoreInteractions(delegate); + assertTrue(canceled.get()); } static class EmptyCall implements Call { diff --git a/retrofit/src/test/java/retrofit2/RetrofitTest.java b/retrofit/src/test/java/retrofit2/RetrofitTest.java index 5608200a14f4ac3d7c4473110ca348db9e889ffc..7b7240dc6a38842861ecb775c4a14cf5b3631cc7 100644 --- a/retrofit/src/test/java/retrofit2/RetrofitTest.java +++ b/retrofit/src/test/java/retrofit2/RetrofitTest.java @@ -40,6 +40,7 @@ import okhttp3.RequestBody; import okhttp3.ResponseBody; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; +import org.jetbrains.annotations.NotNull; import org.junit.Rule; import org.junit.Test; import retrofit2.helpers.DelegatingCallAdapterFactory; @@ -55,16 +56,10 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME; import static okhttp3.mockwebserver.SocketPolicy.DISCONNECT_AT_START; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; -import static org.mockito.Mockito.verifyZeroInteractions; public final class RetrofitTest { @Rule public final MockWebServer server = new MockWebServer(); @@ -147,11 +142,24 @@ public final class RetrofitTest { } @Test public void cloneSharesStatefulInstances() { - CallAdapter.Factory callAdapter = mock(CallAdapter.Factory.class); - Converter.Factory converter = mock(Converter.Factory.class); + CallAdapter.Factory callAdapter = new CallAdapter.Factory() { + @Nullable @Override + public CallAdapter get(Type returnType, Annotation[] annotations, Retrofit retrofit) { + throw new AssertionError(); + } + }; + Converter.Factory converter = new Converter.Factory() {}; HttpUrl baseUrl = server.url("/"); - Executor executor = mock(Executor.class); - okhttp3.Call.Factory callFactory = mock(okhttp3.Call.Factory.class); + Executor executor = new Executor() { + @Override public void execute(@NotNull Runnable command) { + command.run(); + } + }; + okhttp3.Call.Factory callFactory = new okhttp3.Call.Factory() { + @Override public okhttp3.Call newCall(Request request) { + throw new AssertionError(); + } + }; Retrofit one = new Retrofit.Builder() .addCallAdapterFactory(callAdapter) @@ -161,8 +169,13 @@ public final class RetrofitTest { .callFactory(callFactory) .build(); - CallAdapter.Factory callAdapter2 = mock(CallAdapter.Factory.class); - Converter.Factory converter2 = mock(Converter.Factory.class); + CallAdapter.Factory callAdapter2 = new CallAdapter.Factory() { + @Nullable @Override + public CallAdapter get(Type returnType, Annotation[] annotations, Retrofit retrofit) { + throw new AssertionError(); + } + }; + Converter.Factory converter2 = new Converter.Factory() {}; Retrofit two = one.newBuilder() .addCallAdapterFactory(callAdapter2) .addConverterFactory(converter2) @@ -753,7 +766,11 @@ public final class RetrofitTest { } @Test public void callFactoryPropagated() { - okhttp3.Call.Factory callFactory = mock(okhttp3.Call.Factory.class); + okhttp3.Call.Factory callFactory = new okhttp3.Call.Factory() { + @Override public okhttp3.Call newCall(Request request) { + throw new AssertionError(); + } + }; Retrofit retrofit = new Retrofit.Builder() .baseUrl("http://example.com/") .callFactory(callFactory) @@ -771,11 +788,13 @@ public final class RetrofitTest { } @Test public void callFactoryUsed() throws IOException { - okhttp3.Call.Factory callFactory = spy(new okhttp3.Call.Factory() { + final AtomicBoolean called = new AtomicBoolean(); + okhttp3.Call.Factory callFactory = new okhttp3.Call.Factory() { @Override public okhttp3.Call newCall(Request request) { + called.set(true); return new OkHttpClient().newCall(request); } - }); + }; Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .callFactory(callFactory) @@ -785,8 +804,7 @@ public final class RetrofitTest { CallMethod service = retrofit.create(CallMethod.class); service.getResponseBody().execute(); - verify(callFactory).newCall(any(Request.class)); - verifyNoMoreInteractions(callFactory); + assertTrue(called.get()); } @Test public void callFactoryReturningNullThrows() throws IOException { @@ -855,44 +873,47 @@ public final class RetrofitTest { } @Test public void builtInConvertersFirstInClone() { - Converter converter = mock(Converter.class); - Converter.Factory factory = mock(Converter.Factory.class); - Annotation[] annotations = new Annotation[0]; + Converter.Factory factory = new Converter.Factory() { + @Nullable @Override + public Converter responseBodyConverter(Type type, Annotation[] annotations, + Retrofit retrofit) { + throw new AssertionError("User converter factory shouldn't be called for built-in types"); + } + }; Retrofit retrofit = new Retrofit.Builder() .baseUrl("http://example.com/") .addConverterFactory(factory) + .build() + .newBuilder() // Do a newBuilder().builder() dance to force the internal list to clone. .build(); - doReturn(converter).when(factory).responseBodyConverter(Void.class, annotations, retrofit); - - retrofit.newBuilder().build().responseBodyConverter(Void.class, annotations); - - verifyZeroInteractions(factory); + assertNotNull(retrofit.responseBodyConverter(Void.class, new Annotation[0])); } @Test public void requestConverterFactoryQueried() { - Type type = String.class; - Annotation[] parameterAnnotations = new Annotation[0]; - Annotation[] methodAnnotations = new Annotation[1]; - - Converter expectedAdapter = mock(Converter.class); - Converter.Factory factory = mock(Converter.Factory.class); + final Converter expectedAdapter = new Converter() { + @Nullable @Override public RequestBody convert(Object value) { + throw new AssertionError(); + } + }; + Converter.Factory factory = new Converter.Factory() { + @Override public Converter requestBodyConverter(Type type, + Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) { + return String.class.equals(type) + ? expectedAdapter + : null; + } + }; Retrofit retrofit = new Retrofit.Builder() .baseUrl("http://example.com/") .addConverterFactory(factory) .build(); - doReturn(expectedAdapter).when(factory).requestBodyConverter(type, parameterAnnotations, - methodAnnotations, retrofit); - - Converter actualAdapter = retrofit.requestBodyConverter(type, - parameterAnnotations, methodAnnotations); + Converter actualAdapter = + retrofit.requestBodyConverter(String.class, new Annotation[0], new Annotation[0]); assertThat(actualAdapter).isSameAs(expectedAdapter); - - verify(factory).requestBodyConverter(type, parameterAnnotations, methodAnnotations, retrofit); - verifyNoMoreInteractions(factory); } @Test public void requestConverterFactoryNoMatchThrows() { @@ -953,24 +974,29 @@ public final class RetrofitTest { } @Test public void responseConverterFactoryQueried() { - Type type = String.class; - Annotation[] annotations = new Annotation[0]; - - Converter expectedAdapter = mock(Converter.class); - Converter.Factory factory = mock(Converter.Factory.class); + final Converter expectedAdapter = new Converter() { + @Nullable @Override public Object convert(ResponseBody value) { + throw new AssertionError(); + } + }; + Converter.Factory factory = new Converter.Factory() { + @Nullable @Override + public Converter responseBodyConverter(Type type, Annotation[] annotations, + Retrofit retrofit) { + return String.class.equals(type) + ? expectedAdapter + : null; + } + }; Retrofit retrofit = new Retrofit.Builder() .baseUrl("http://example.com/") .addConverterFactory(factory) .build(); - doReturn(expectedAdapter).when(factory).responseBodyConverter(type, annotations, retrofit); - - Converter actualAdapter = retrofit.responseBodyConverter(type, annotations); + Converter actualAdapter = + retrofit.responseBodyConverter(String.class, new Annotation[0]); assertThat(actualAdapter).isSameAs(expectedAdapter); - - verify(factory).responseBodyConverter(type, annotations, retrofit); - verifyNoMoreInteractions(factory); } @Test public void responseConverterFactoryNoMatchThrows() { @@ -1031,28 +1057,33 @@ public final class RetrofitTest { } @Test public void stringConverterFactoryQueried() { - Type type = Object.class; - Annotation[] annotations = new Annotation[0]; - - Converter expectedConverter = mock(Converter.class); - Converter.Factory factory = mock(Converter.Factory.class); + final Converter expectedConverter = new Converter() { + @Nullable @Override public String convert(Object value) { + throw new AssertionError(); + } + }; + Converter.Factory factory = new Converter.Factory() { + @Nullable @Override + public Converter stringConverter(Type type, Annotation[] annotations, + Retrofit retrofit) { + return Object.class.equals(type) + ? expectedConverter + : null; + } + }; Retrofit retrofit = new Retrofit.Builder() .baseUrl("http://example.com/") .addConverterFactory(factory) .build(); - doReturn(expectedConverter).when(factory).stringConverter(type, annotations, retrofit); - - Converter actualConverter = retrofit.stringConverter(type, annotations); + Converter actualConverter = + retrofit.stringConverter(Object.class, new Annotation[0]); assertThat(actualConverter).isSameAs(expectedConverter); - - verify(factory).stringConverter(type, annotations, retrofit); - verifyNoMoreInteractions(factory); } @Test public void converterFactoryPropagated() { - Converter.Factory factory = mock(Converter.Factory.class); + Converter.Factory factory = new Converter.Factory() {}; Retrofit retrofit = new Retrofit.Builder() .baseUrl("http://example.com/") .addConverterFactory(factory) @@ -1077,7 +1108,12 @@ public final class RetrofitTest { } @Test public void callAdapterFactoryPropagated() { - CallAdapter.Factory factory = mock(CallAdapter.Factory.class); + CallAdapter.Factory factory = new CallAdapter.Factory() { + @Nullable @Override + public CallAdapter get(Type returnType, Annotation[] annotations, Retrofit retrofit) { + throw new AssertionError(); + } + }; Retrofit retrofit = new Retrofit.Builder() .baseUrl("http://example.com/") .addCallAdapterFactory(factory) @@ -1086,38 +1122,55 @@ public final class RetrofitTest { } @Test public void callAdapterFactoryQueried() { - Type type = String.class; - Annotation[] annotations = new Annotation[0]; - - CallAdapter expectedAdapter = mock(CallAdapter.class); - CallAdapter.Factory factory = mock(CallAdapter.Factory.class); + final CallAdapter expectedAdapter = new CallAdapter() { + @Override public Type responseType() { + throw new AssertionError(); + } + @Override public Object adapt(Call call) { + throw new AssertionError(); + } + }; + CallAdapter.Factory factory = new CallAdapter.Factory() { + @Nullable @Override + public CallAdapter get(Type returnType, Annotation[] annotations, Retrofit retrofit) { + return String.class.equals(returnType) + ? expectedAdapter + : null; + } + }; Retrofit retrofit = new Retrofit.Builder() .baseUrl("http://example.com/") .addCallAdapterFactory(factory) .build(); - doReturn(expectedAdapter).when(factory).get(type, annotations, retrofit); - - CallAdapter actualAdapter = retrofit.callAdapter(type, annotations); + CallAdapter actualAdapter = retrofit.callAdapter(String.class, new Annotation[0]); assertThat(actualAdapter).isSameAs(expectedAdapter); - - verify(factory).get(type, annotations, retrofit); - verifyNoMoreInteractions(factory); } @Test public void callAdapterFactoryQueriedCanDelegate() { - Type type = String.class; - Annotation[] annotations = new Annotation[0]; - - CallAdapter expectedAdapter = mock(CallAdapter.class); - CallAdapter.Factory factory2 = mock(CallAdapter.Factory.class); - CallAdapter.Factory factory1 = spy(new CallAdapter.Factory() { + final CallAdapter expectedAdapter = new CallAdapter() { + @Override public Type responseType() { + throw new AssertionError(); + } + @Override public Object adapt(Call call) { + throw new AssertionError(); + } + }; + CallAdapter.Factory factory2 = new CallAdapter.Factory() { @Override public CallAdapter get(Type returnType, Annotation[] annotations, Retrofit retrofit) { + return expectedAdapter; + } + }; + final AtomicBoolean factory1called = new AtomicBoolean(); + CallAdapter.Factory factory1 = new CallAdapter.Factory() { + @Override + public CallAdapter get(Type returnType, Annotation[] annotations, Retrofit retrofit) { + factory1called.set(true); return retrofit.nextCallAdapter(this, returnType, annotations); } - }); + }; Retrofit retrofit = new Retrofit.Builder() .baseUrl("http://example.com/") @@ -1125,35 +1178,45 @@ public final class RetrofitTest { .addCallAdapterFactory(factory2) .build(); - doReturn(expectedAdapter).when(factory2).get(type, annotations, retrofit); - - CallAdapter actualAdapter = retrofit.callAdapter(type, annotations); + CallAdapter actualAdapter = retrofit.callAdapter(String.class, new Annotation[0]); assertThat(actualAdapter).isSameAs(expectedAdapter); - - verify(factory1).get(type, annotations, retrofit); - verifyNoMoreInteractions(factory1); - verify(factory2).get(type, annotations, retrofit); - verifyNoMoreInteractions(factory2); + assertTrue(factory1called.get()); } @Test public void callAdapterFactoryQueriedCanDelegateTwiceWithoutRecursion() { Type type = String.class; Annotation[] annotations = new Annotation[0]; - CallAdapter expectedAdapter = mock(CallAdapter.class); - CallAdapter.Factory factory3 = mock(CallAdapter.Factory.class); - CallAdapter.Factory factory2 = spy(new CallAdapter.Factory() { + final CallAdapter expectedAdapter = new CallAdapter() { + @Override public Type responseType() { + throw new AssertionError(); + } + @Override public Object adapt(Call call) { + throw new AssertionError(); + } + }; + CallAdapter.Factory factory3 = new CallAdapter.Factory() { @Override public CallAdapter get(Type returnType, Annotation[] annotations, Retrofit retrofit) { + return expectedAdapter; + } + }; + final AtomicBoolean factory2called = new AtomicBoolean(); + CallAdapter.Factory factory2 = new CallAdapter.Factory() { + @Override + public CallAdapter get(Type returnType, Annotation[] annotations, Retrofit retrofit) { + factory2called.set(true); return retrofit.nextCallAdapter(this, returnType, annotations); } - }); - CallAdapter.Factory factory1 = spy(new CallAdapter.Factory() { + }; + final AtomicBoolean factory1called = new AtomicBoolean(); + CallAdapter.Factory factory1 = new CallAdapter.Factory() { @Override public CallAdapter get(Type returnType, Annotation[] annotations, Retrofit retrofit) { + factory1called.set(true); return retrofit.nextCallAdapter(this, returnType, annotations); } - }); + }; Retrofit retrofit = new Retrofit.Builder() .baseUrl("http://example.com/") @@ -1162,17 +1225,10 @@ public final class RetrofitTest { .addCallAdapterFactory(factory3) .build(); - doReturn(expectedAdapter).when(factory3).get(type, annotations, retrofit); - CallAdapter actualAdapter = retrofit.callAdapter(type, annotations); assertThat(actualAdapter).isSameAs(expectedAdapter); - - verify(factory1).get(type, annotations, retrofit); - verifyNoMoreInteractions(factory1); - verify(factory2).get(type, annotations, retrofit); - verifyNoMoreInteractions(factory2); - verify(factory3).get(type, annotations, retrofit); - verifyNoMoreInteractions(factory3); + assertTrue(factory1called.get()); + assertTrue(factory2called.get()); } @Test public void callAdapterFactoryNoMatchThrows() { @@ -1274,7 +1330,11 @@ public final class RetrofitTest { } @Test public void callbackExecutorPropagated() { - Executor executor = mock(Executor.class); + Executor executor = new Executor() { + @Override public void execute(@NotNull Runnable command) { + throw new AssertionError(); + } + }; Retrofit retrofit = new Retrofit.Builder() .baseUrl("http://example.com/") .callbackExecutor(executor) @@ -1283,11 +1343,14 @@ public final class RetrofitTest { } @Test public void callbackExecutorUsedForSuccess() throws InterruptedException { - Executor executor = spy(new Executor() { + final CountDownLatch runnableLatch = new CountDownLatch(1); + final AtomicReference runnableRef = new AtomicReference<>(); + Executor executor = new Executor() { @Override public void execute(Runnable command) { - command.run(); + runnableRef.set(command); + runnableLatch.countDown(); } - }); + }; Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .callbackExecutor(executor) @@ -1297,28 +1360,33 @@ public final class RetrofitTest { server.enqueue(new MockResponse()); - final CountDownLatch latch = new CountDownLatch(1); + final CountDownLatch callbackLatch = new CountDownLatch(1); call.enqueue(new Callback() { @Override public void onResponse(Call call, Response response) { - latch.countDown(); + callbackLatch.countDown(); } @Override public void onFailure(Call call, Throwable t) { t.printStackTrace(); } }); - assertTrue(latch.await(2, TimeUnit.SECONDS)); - verify(executor).execute(any(Runnable.class)); - verifyNoMoreInteractions(executor); + assertTrue(runnableLatch.await(2, TimeUnit.SECONDS)); + assertEquals(1, callbackLatch.getCount()); // Callback not run yet. + + runnableRef.get().run(); + assertTrue(callbackLatch.await(2, TimeUnit.SECONDS)); } @Test public void callbackExecutorUsedForFailure() throws InterruptedException { - Executor executor = spy(new Executor() { + final CountDownLatch runnableLatch = new CountDownLatch(1); + final AtomicReference runnableRef = new AtomicReference<>(); + Executor executor = new Executor() { @Override public void execute(Runnable command) { - command.run(); + runnableRef.set(command); + runnableLatch.countDown(); } - }); + }; Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .callbackExecutor(executor) @@ -1328,20 +1396,22 @@ public final class RetrofitTest { server.enqueue(new MockResponse().setSocketPolicy(DISCONNECT_AT_START)); - final CountDownLatch latch = new CountDownLatch(1); + final CountDownLatch callbackLatch = new CountDownLatch(1); call.enqueue(new Callback() { @Override public void onResponse(Call call, Response response) { throw new AssertionError(); } @Override public void onFailure(Call call, Throwable t) { - latch.countDown(); + callbackLatch.countDown(); } }); - assertTrue(latch.await(2, TimeUnit.SECONDS)); - verify(executor).execute(any(Runnable.class)); - verifyNoMoreInteractions(executor); + assertTrue(runnableLatch.await(2, TimeUnit.SECONDS)); + assertEquals(1, callbackLatch.getCount()); // Callback not run yet. + + runnableRef.get().run(); + assertTrue(callbackLatch.await(2, TimeUnit.SECONDS)); } @Test public void skippedCallbackExecutorNotUsedForSuccess() throws InterruptedException {