Skip to content

Commit 4899ed5

Browse files
committed
First tests
1 parent e46698e commit 4899ed5

7 files changed

Lines changed: 157 additions & 17 deletions

File tree

.idea/runConfigurations/Run_all_JUnit_tests.xml

Lines changed: 14 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

app/build.gradle

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,9 @@ dependencies {
9191

9292
// Testing libs
9393
testImplementation "junit:junit:$versions.junit"
94+
testImplementation "org.mockito:mockito-core:$versions.mockito"
95+
testImplementation "org.powermock:powermock-module-junit4:$versions.powermock"
96+
testImplementation "org.powermock:powermock-api-mockito2:$versions.powermock"
9497
androidTestImplementation "androidx.test.ext:junit:$versions.junitExt"
9598
androidTestImplementation "androidx.test.espresso:espresso-core:$versions.espresso"
9699
}

app/src/main/java/com/simonesestito/shopsqueue/api/ApiCallAdapter.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,14 @@
2525
import java.lang.reflect.Type;
2626
import java.util.Objects;
2727

28+
import okhttp3.internal.annotations.EverythingIsNonNull;
2829
import retrofit2.Call;
2930
import retrofit2.CallAdapter;
3031
import retrofit2.Callback;
3132
import retrofit2.Response;
3233
import retrofit2.Retrofit;
3334

35+
@EverythingIsNonNull
3436
public class ApiCallAdapter<T> implements CallAdapter<T, ApiResponse<T>> {
3537
private final Type responseType;
3638

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
/*
2+
* Copyright 2020 Simone Sestito
3+
* This file is part of Shops Queue.
4+
*
5+
* Shops Queue is free software: you can redistribute it and/or modify
6+
* it under the terms of the GNU General Public License as published by
7+
* the Free Software Foundation, either version 3 of the License, or
8+
* (at your option) any later version.
9+
*
10+
* Shops Queue is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
* GNU General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU General Public License
16+
* along with Shops Queue. If not, see <http://www.gnu.org/licenses/>.
17+
*/
18+
19+
package com.simonesestito.shopsqueue;
20+
21+
import android.os.Handler;
22+
import android.os.Looper;
23+
24+
import org.mockito.stubbing.Answer;
25+
import org.powermock.api.mockito.PowerMockito;
26+
27+
import java.util.concurrent.Executors;
28+
import java.util.concurrent.ScheduledExecutorService;
29+
import java.util.concurrent.TimeUnit;
30+
31+
import static org.mockito.ArgumentMatchers.any;
32+
import static org.mockito.ArgumentMatchers.anyLong;
33+
import static org.mockito.Mockito.mock;
34+
import static org.mockito.Mockito.when;
35+
36+
/**
37+
* Utility methods that unit tests can use to do common android library mocking that might be needed.
38+
* <p>
39+
* Credits: https://gist.github.com/dpmedeiros/7f7724fdf13fc5390bb05958448cdcad
40+
*/
41+
public class AndroidMockUtil {
42+
private final static ScheduledExecutorService mainThread = Executors.newSingleThreadScheduledExecutor();
43+
44+
private AndroidMockUtil() {
45+
}
46+
47+
/**
48+
* Mocks main thread handler post() and postDelayed() for use in Android unit tests
49+
* <p>
50+
* To use this:
51+
* <ol>
52+
* <li>Call this method in an {@literal @}Before method of your test.</li>
53+
* <li>Place Looper.class in the {@literal @}PrepareForTest annotation before your test class.</li>
54+
* <li>any class under test that needs to call {@code new Handler(Looper.getMainLooper())} should be placed
55+
* in the {@literal @}PrepareForTest annotation as well.</li>
56+
* </ol>
57+
*/
58+
public static void mockMainThreadHandler() throws Exception {
59+
PowerMockito.mockStatic(Looper.class);
60+
Looper mockMainThreadLooper = mock(Looper.class);
61+
when(Looper.getMainLooper()).thenReturn(mockMainThreadLooper);
62+
Handler mockMainThreadHandler = mock(Handler.class);
63+
64+
Answer<Boolean> handlerPostAnswer = invocation -> {
65+
Runnable runnable = invocation.getArgument(0, Runnable.class);
66+
Long delay = 0L;
67+
if (invocation.getArguments().length > 1) {
68+
delay = invocation.getArgument(1, Long.class);
69+
}
70+
if (runnable != null) {
71+
mainThread.schedule(runnable, delay, TimeUnit.MILLISECONDS);
72+
}
73+
return true;
74+
};
75+
76+
when(mockMainThreadHandler.post(any(Runnable.class))).then(handlerPostAnswer);
77+
when(mockMainThreadHandler.postDelayed(any(Runnable.class), anyLong())).then(handlerPostAnswer);
78+
PowerMockito.whenNew(Handler.class).withArguments(mockMainThreadLooper).thenReturn(mockMainThreadHandler);
79+
}
80+
}

app/src/test/java/com/simonesestito/shopsqueue/ExampleUnitTest.java

Lines changed: 0 additions & 17 deletions
This file was deleted.
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/*
2+
* Copyright 2020 Simone Sestito
3+
* This file is part of Shops Queue.
4+
*
5+
* Shops Queue is free software: you can redistribute it and/or modify
6+
* it under the terms of the GNU General Public License as published by
7+
* the Free Software Foundation, either version 3 of the License, or
8+
* (at your option) any later version.
9+
*
10+
* Shops Queue is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
* GNU General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU General Public License
16+
* along with Shops Queue. If not, see <http://www.gnu.org/licenses/>.
17+
*/
18+
19+
package com.simonesestito.shopsqueue.api;
20+
21+
import android.os.Looper;
22+
23+
import com.simonesestito.shopsqueue.AndroidMockUtil;
24+
import com.simonesestito.shopsqueue.util.functional.Callback;
25+
26+
import org.junit.Before;
27+
import org.junit.Test;
28+
import org.junit.runner.RunWith;
29+
import org.mockito.Mock;
30+
import org.powermock.core.classloader.annotations.PrepareForTest;
31+
import org.powermock.modules.junit4.PowerMockRunner;
32+
33+
import static org.mockito.Mockito.verify;
34+
35+
@RunWith(PowerMockRunner.class)
36+
@PrepareForTest(Looper.class)
37+
public class ApiResponseTest {
38+
@Mock
39+
public Callback<Object> callback;
40+
41+
@Before
42+
public void mockMainThread() throws Exception {
43+
AndroidMockUtil.mockMainThreadHandler();
44+
}
45+
46+
@Test
47+
public void onResultHandlerIsCalled() {
48+
ApiResponse<Object> apiResponse = new ApiResponse<>();
49+
apiResponse.onResult(callback);
50+
51+
Object result = new Object();
52+
apiResponse.emitResult(result);
53+
54+
verify(callback).onResult(result);
55+
}
56+
}

versions.gradle

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,5 +41,7 @@ versions.licensesLib = '17.0.0'
4141
versions.junit = '4.12'
4242
versions.junitExt = '1.1.1'
4343
versions.espresso = '3.2.0'
44+
versions.mockito = '3.3.3'
45+
versions.powermock = '2.0.2'
4446

4547
ext.versions = versions

0 commit comments

Comments
 (0)