Skip to content

Commit 6e37fb9

Browse files
authored
[FLoC] Change FLoC instrumental tests to be unit tests. (#1058)
* [FLoC] Change FLoC instrumental tests to be unit tests.
1 parent fd0a4fa commit 6e37fb9

File tree

5 files changed

+123
-54
lines changed

5 files changed

+123
-54
lines changed

firebase-segmentation/firebase-segmentation.gradle

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -54,13 +54,7 @@ dependencies {
5454
testImplementation 'androidx.test:core:1.2.0'
5555
testImplementation 'junit:junit:4.12'
5656
testImplementation "org.robolectric:robolectric:$robolectricVersion"
57-
58-
androidTestImplementation "androidx.annotation:annotation:1.1.0"
59-
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
60-
androidTestImplementation 'androidx.test:rules:1.2.0'
61-
androidTestImplementation 'androidx.test:runner:1.2.0'
62-
androidTestImplementation "com.google.truth:truth:$googleTruthVersion"
63-
androidTestImplementation 'junit:junit:4.12'
64-
androidTestImplementation 'org.mockito:mockito-core:2.25.0'
65-
androidTestImplementation 'org.mockito:mockito-android:2.25.0'
57+
testImplementation "com.google.truth:truth:$googleTruthVersion"
58+
testImplementation 'org.mockito:mockito-core:2.25.0'
59+
testImplementation 'org.mockito:mockito-inline:2.25.0'
6660
}

firebase-segmentation/src/androidTest/AndroidManifest.xml

Lines changed: 0 additions & 26 deletions
This file was deleted.
Lines changed: 48 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,13 @@
1717
import static com.google.common.truth.Truth.assertThat;
1818
import static org.junit.Assert.assertNull;
1919
import static org.junit.Assert.fail;
20+
import static org.mockito.ArgumentMatchers.any;
2021
import static org.mockito.ArgumentMatchers.anyLong;
2122
import static org.mockito.ArgumentMatchers.anyString;
22-
import static org.mockito.Mockito.any;
2323
import static org.mockito.Mockito.when;
2424

2525
import androidx.annotation.NonNull;
2626
import androidx.test.core.app.ApplicationProvider;
27-
import androidx.test.ext.junit.runners.AndroidJUnit4;
2827
import com.google.android.gms.tasks.Tasks;
2928
import com.google.firebase.FirebaseApp;
3029
import com.google.firebase.FirebaseOptions;
@@ -34,6 +33,10 @@
3433
import com.google.firebase.segmentation.local.CustomInstallationIdCacheEntryValue;
3534
import com.google.firebase.segmentation.remote.SegmentationServiceClient;
3635
import java.util.concurrent.ExecutionException;
36+
import java.util.concurrent.ExecutorService;
37+
import java.util.concurrent.LinkedBlockingQueue;
38+
import java.util.concurrent.ThreadPoolExecutor;
39+
import java.util.concurrent.TimeUnit;
3740
import org.junit.After;
3841
import org.junit.Before;
3942
import org.junit.FixMethodOrder;
@@ -42,26 +45,24 @@
4245
import org.junit.runners.MethodSorters;
4346
import org.mockito.Mock;
4447
import org.mockito.MockitoAnnotations;
48+
import org.robolectric.RobolectricTestRunner;
4549

46-
/**
47-
* Instrumented test, which will execute on an Android device.
48-
*
49-
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
50-
*/
51-
@RunWith(AndroidJUnit4.class)
50+
@RunWith(RobolectricTestRunner.class)
5251
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
53-
public class FirebaseSegmentationInstrumentedTest {
54-
52+
public class FirebaseSegmentationTest {
5553
private static final String CUSTOM_INSTALLATION_ID = "123";
5654
private static final String FIREBASE_INSTANCE_ID = "cAAAAAAAAAA";
5755

5856
private FirebaseApp firebaseApp;
5957
@Mock private FirebaseInstanceId firebaseInstanceId;
6058
@Mock private SegmentationServiceClient backendClientReturnsOk;
6159
@Mock private SegmentationServiceClient backendClientReturnsError;
60+
6261
private CustomInstallationIdCache actualCache;
6362
@Mock private CustomInstallationIdCache cacheReturnsError;
6463

64+
private ExecutorService taskExecutor;
65+
6566
@Before
6667
public void setUp() {
6768
MockitoAnnotations.initMocks(this);
@@ -105,6 +106,8 @@ public String getToken() {
105106
}));
106107
when(cacheReturnsError.insertOrUpdateCacheEntry(any())).thenReturn(false);
107108
when(cacheReturnsError.readCacheEntryValue()).thenReturn(null);
109+
110+
taskExecutor = new ThreadPoolExecutor(0, 1, 30L, TimeUnit.SECONDS, new LinkedBlockingQueue<>());
108111
}
109112

110113
@After
@@ -119,7 +122,11 @@ public void testUpdateCustomInstallationId_CacheOk_BackendOk() throws Exception
119122
firebaseApp, firebaseInstanceId, actualCache, backendClientReturnsOk);
120123

121124
// No exception, means success.
122-
assertNull(Tasks.await(firebaseSegmentation.setCustomInstallationId(CUSTOM_INSTALLATION_ID)));
125+
TestOnCompleteListener<Void> onCompleteListener = new TestOnCompleteListener<>();
126+
firebaseSegmentation
127+
.setCustomInstallationId(CUSTOM_INSTALLATION_ID)
128+
.addOnCompleteListener(taskExecutor, onCompleteListener);
129+
assertNull(onCompleteListener.await());
123130
CustomInstallationIdCacheEntryValue entryValue = actualCache.readCacheEntryValue();
124131
assertThat(entryValue.getCustomInstallationId()).isEqualTo(CUSTOM_INSTALLATION_ID);
125132
assertThat(entryValue.getFirebaseInstanceId()).isEqualTo(FIREBASE_INSTANCE_ID);
@@ -135,7 +142,11 @@ public void testUpdateCustomInstallationId_CacheOk_BackendError_Retryable()
135142

136143
// Expect exception
137144
try {
138-
Tasks.await(firebaseSegmentation.setCustomInstallationId(CUSTOM_INSTALLATION_ID));
145+
TestOnCompleteListener<Void> onCompleteListener = new TestOnCompleteListener<>();
146+
firebaseSegmentation
147+
.setCustomInstallationId(CUSTOM_INSTALLATION_ID)
148+
.addOnCompleteListener(taskExecutor, onCompleteListener);
149+
onCompleteListener.await();
139150
fail();
140151
} catch (ExecutionException expected) {
141152
Throwable cause = expected.getCause();
@@ -163,7 +174,11 @@ public void testUpdateCustomInstallationId_CacheOk_BackendError_NotRetryable()
163174

164175
// Expect exception
165176
try {
166-
Tasks.await(firebaseSegmentation.setCustomInstallationId(CUSTOM_INSTALLATION_ID));
177+
TestOnCompleteListener<Void> onCompleteListener = new TestOnCompleteListener<>();
178+
firebaseSegmentation
179+
.setCustomInstallationId(CUSTOM_INSTALLATION_ID)
180+
.addOnCompleteListener(taskExecutor, onCompleteListener);
181+
onCompleteListener.await();
167182
fail();
168183
} catch (ExecutionException expected) {
169184
Throwable cause = expected.getCause();
@@ -184,7 +199,11 @@ public void testUpdateCustomInstallationId_CacheError_BackendOk() throws Interru
184199

185200
// Expect exception
186201
try {
187-
Tasks.await(firebaseSegmentation.setCustomInstallationId(CUSTOM_INSTALLATION_ID));
202+
TestOnCompleteListener<Void> onCompleteListener = new TestOnCompleteListener<>();
203+
firebaseSegmentation
204+
.setCustomInstallationId(CUSTOM_INSTALLATION_ID)
205+
.addOnCompleteListener(taskExecutor, onCompleteListener);
206+
onCompleteListener.await();
188207
fail();
189208
} catch (ExecutionException expected) {
190209
Throwable cause = expected.getCause();
@@ -206,7 +225,11 @@ public void testClearCustomInstallationId_CacheOk_BackendOk() throws Exception {
206225
firebaseApp, firebaseInstanceId, actualCache, backendClientReturnsOk);
207226

208227
// No exception, means success.
209-
assertNull(Tasks.await(firebaseSegmentation.setCustomInstallationId(null)));
228+
TestOnCompleteListener<Void> onCompleteListener = new TestOnCompleteListener<>();
229+
firebaseSegmentation
230+
.setCustomInstallationId(null)
231+
.addOnCompleteListener(taskExecutor, onCompleteListener);
232+
assertNull(onCompleteListener.await());
210233
CustomInstallationIdCacheEntryValue entryValue = actualCache.readCacheEntryValue();
211234
assertNull(entryValue);
212235
}
@@ -224,7 +247,11 @@ public void testClearCustomInstallationId_CacheOk_BackendError() throws Exceptio
224247

225248
// Expect exception
226249
try {
227-
Tasks.await(firebaseSegmentation.setCustomInstallationId(null));
250+
TestOnCompleteListener<Void> onCompleteListener = new TestOnCompleteListener<>();
251+
firebaseSegmentation
252+
.setCustomInstallationId(null)
253+
.addOnCompleteListener(taskExecutor, onCompleteListener);
254+
onCompleteListener.await();
228255
fail();
229256
} catch (ExecutionException expected) {
230257
Throwable cause = expected.getCause();
@@ -248,7 +275,11 @@ public void testClearCustomInstallationId_CacheError_BackendOk() throws Interrup
248275

249276
// Expect exception
250277
try {
251-
Tasks.await(firebaseSegmentation.setCustomInstallationId(CUSTOM_INSTALLATION_ID));
278+
TestOnCompleteListener<Void> onCompleteListener = new TestOnCompleteListener<>();
279+
firebaseSegmentation
280+
.setCustomInstallationId(null)
281+
.addOnCompleteListener(taskExecutor, onCompleteListener);
282+
onCompleteListener.await();
252283
fail();
253284
} catch (ExecutionException expected) {
254285
Throwable cause = expected.getCause();
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
// Copyright 2019 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package com.google.firebase.segmentation;
16+
17+
import androidx.annotation.NonNull;
18+
import com.google.android.gms.tasks.OnCompleteListener;
19+
import com.google.android.gms.tasks.Task;
20+
import java.io.IOException;
21+
import java.util.concurrent.CountDownLatch;
22+
import java.util.concurrent.ExecutionException;
23+
import java.util.concurrent.TimeUnit;
24+
25+
/**
26+
* Helper listener that works around a limitation of the Tasks API where await() cannot be called on
27+
* the main thread. This listener works around it by running itself on a different thread, thus
28+
* allowing the main thread to be woken up when the Tasks complete.
29+
*/
30+
public class TestOnCompleteListener<TResult> implements OnCompleteListener<TResult> {
31+
private static final long TIMEOUT_MS = 5000;
32+
private final CountDownLatch latch = new CountDownLatch(1);
33+
private Task<TResult> task;
34+
private volatile TResult result;
35+
private volatile Exception exception;
36+
private volatile boolean successful;
37+
38+
@Override
39+
public void onComplete(@NonNull Task<TResult> task) {
40+
this.task = task;
41+
successful = task.isSuccessful();
42+
if (successful) {
43+
result = task.getResult();
44+
} else {
45+
exception = task.getException();
46+
}
47+
latch.countDown();
48+
}
49+
50+
/** Blocks until the {@link #onComplete} is called. */
51+
public TResult await() throws InterruptedException, ExecutionException {
52+
if (!latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)) {
53+
throw new InterruptedException("timed out waiting for result");
54+
}
55+
if (successful) {
56+
return result;
57+
} else {
58+
if (exception instanceof InterruptedException) {
59+
throw (InterruptedException) exception;
60+
}
61+
if (exception instanceof SetCustomInstallationIdException) {
62+
throw new ExecutionException(exception);
63+
}
64+
if (exception instanceof IOException) {
65+
throw new ExecutionException(exception);
66+
}
67+
throw new IllegalStateException("got an unexpected exception type", exception);
68+
}
69+
}
70+
}
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,16 @@
1919
import static org.junit.Assert.assertTrue;
2020

2121
import androidx.test.core.app.ApplicationProvider;
22-
import androidx.test.ext.junit.runners.AndroidJUnit4;
2322
import com.google.firebase.FirebaseApp;
2423
import com.google.firebase.FirebaseOptions;
2524
import org.junit.After;
2625
import org.junit.Before;
2726
import org.junit.Test;
2827
import org.junit.runner.RunWith;
28+
import org.robolectric.RobolectricTestRunner;
2929

3030
/** Instrumented tests for {@link CustomInstallationIdCache} */
31-
@RunWith(AndroidJUnit4.class)
31+
@RunWith(RobolectricTestRunner.class)
3232
public class CustomInstallationIdCacheTest {
3333

3434
private FirebaseApp firebaseApp0;

0 commit comments

Comments
 (0)