Skip to content

Commit

Permalink
Refactor unit tests.
Browse files Browse the repository at this point in the history
  • Loading branch information
patloew committed Oct 29, 2016
1 parent 4889d0e commit f552cec
Show file tree
Hide file tree
Showing 14 changed files with 1,939 additions and 1,389 deletions.
11 changes: 7 additions & 4 deletions library/src/main/java/com/patloew/rxwear/BaseRx.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ abstract class BaseRx<T> {
private final Context ctx;
private final Api<? extends Api.ApiOptions.NotRequiredOptions>[] services;
private final Scope[] scopes;
private final Long timeoutTime;
private final TimeUnit timeoutUnit;
final Long timeoutTime;
final TimeUnit timeoutUnit;

protected BaseRx(@NonNull RxWear rxWear, Long timeout, TimeUnit timeUnit) {
this.ctx = rxWear.ctx;
Expand Down Expand Up @@ -69,10 +69,13 @@ protected final <T extends Result> void setupWearPendingResult(PendingResult<T>
}
}

protected final GoogleApiClient createApiClient(ApiClientConnectionCallbacks apiClientConnectionCallbacks) {
protected GoogleApiClient.Builder getApiClientBuilder() {
return new GoogleApiClient.Builder(ctx);
}

GoogleApiClient.Builder apiClientBuilder = new GoogleApiClient.Builder(ctx);
protected GoogleApiClient createApiClient(ApiClientConnectionCallbacks apiClientConnectionCallbacks) {

GoogleApiClient.Builder apiClientBuilder = getApiClientBuilder();

for (Api<? extends Api.ApiOptions.NotRequiredOptions> service : services) {
apiClientBuilder.addApi(service);
Expand Down
86 changes: 86 additions & 0 deletions library/src/test/java/com/patloew/rxwear/BaseObservableTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package com.patloew.rxwear;

import android.support.v4.content.ContextCompat;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.Status;
import com.google.android.gms.wearable.Wearable;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Matchers;
import org.mockito.MockitoAnnotations;
import org.powermock.core.classloader.annotations.PrepareOnlyThisForTest;
import org.powermock.core.classloader.annotations.SuppressStaticInitializationFor;
import org.powermock.modules.junit4.PowerMockRunner;

import rx.Observable;
import rx.Subscriber;
import rx.observers.TestSubscriber;

import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.spy;

@RunWith(PowerMockRunner.class)
@PrepareOnlyThisForTest({ ContextCompat.class, Wearable.class, Status.class, ConnectionResult.class })
@SuppressStaticInitializationFor("com.google.android.gms.wearable.Wearable")
public class BaseObservableTest extends BaseOnSubscribeTest {

@Before
public void setup() throws Exception {
MockitoAnnotations.initMocks(this);
super.setup();
}

@Test
public void BaseObservable_ApiClient_Connected() {
final Object object = new Object();
TestSubscriber<Object> sub = new TestSubscriber<>();
BaseObservable<Object> observable = spy(new BaseObservable<Object>(rxWear, null, null) {
@Override
protected void onGoogleApiClientReady(GoogleApiClient apiClient, Subscriber<? super Object> subscriber) {
subscriber.onNext(object);
subscriber.onCompleted();
}
});

doAnswer(invocation -> {
BaseRx.ApiClientConnectionCallbacks callbacks = invocation.getArgumentAt(0, BaseRx.ApiClientConnectionCallbacks.class);
callbacks.setClient(apiClient);
callbacks.onConnected(null);
return apiClient;
}).when(observable).createApiClient(Matchers.any(BaseRx.ApiClientConnectionCallbacks.class));

Observable.create(observable).subscribe(sub);

sub.assertValue(object);
sub.assertCompleted();
}

@Test
public void BaseObservable_ApiClient_ConnectionSuspended() {
final Object object = new Object();
TestSubscriber<Object> sub = new TestSubscriber<>();
BaseObservable<Object> observable = spy(new BaseObservable<Object>(rxWear, null, null) {
@Override
protected void onGoogleApiClientReady(GoogleApiClient apiClient, Subscriber<? super Object> subscriber) {
subscriber.onNext(object);
subscriber.onCompleted();
}
});

doAnswer(invocation -> {
BaseRx.ApiClientConnectionCallbacks callbacks = invocation.getArgumentAt(0, BaseRx.ApiClientConnectionCallbacks.class);
callbacks.setClient(apiClient);
callbacks.onConnectionSuspended(0);
return apiClient;
}).when(observable).createApiClient(Matchers.any(BaseRx.ApiClientConnectionCallbacks.class));

Observable.create(observable).subscribe(sub);

sub.assertNoValues();
sub.assertError(GoogleAPIConnectionSuspendedException.class);
}
}
170 changes: 170 additions & 0 deletions library/src/test/java/com/patloew/rxwear/BaseOnSubscribeTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
package com.patloew.rxwear;

import android.app.PendingIntent;
import android.support.annotation.CallSuper;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.PendingResult;
import com.google.android.gms.common.api.Result;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.common.api.Status;
import com.google.android.gms.wearable.CapabilityApi;
import com.google.android.gms.wearable.ChannelApi;
import com.google.android.gms.wearable.DataApi;
import com.google.android.gms.wearable.MessageApi;
import com.google.android.gms.wearable.NodeApi;
import com.google.android.gms.wearable.Wearable;

import org.mockito.Matchers;
import org.mockito.Mock;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.reflect.Whitebox;

import java.lang.reflect.Field;
import java.util.Set;

import rx.SingleSubscriber;
import rx.Subscriber;
import rx.observers.TestSubscriber;

import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doReturn;

public abstract class BaseOnSubscribeTest extends BaseTest {

@Mock GoogleApiClient apiClient;
@Mock Status status;
@Mock ConnectionResult connectionResult;
@Mock PendingResult pendingResult;
@Mock PendingIntent pendingIntent;

@Mock DataApi dataApi;
@Mock CapabilityApi capabilityApi;
@Mock MessageApi messageApi;
@Mock NodeApi nodeApi;
@Mock ChannelApi channelApi;

@CallSuper
public void setup() throws Exception {
PowerMockito.mockStatic(Wearable.class);
Whitebox.setInternalState(Wearable.class, dataApi);
Whitebox.setInternalState(Wearable.class, capabilityApi);
Whitebox.setInternalState(Wearable.class, messageApi);
Whitebox.setInternalState(Wearable.class, nodeApi);
Whitebox.setInternalState(Wearable.class, channelApi);

doReturn(status).when(status).getStatus();

super.setup();
}

// Mock GoogleApiClient connection success behaviour
protected <T> void setupBaseObservableSuccess(final BaseObservable<T> baseObservable) {
setupBaseObservableSuccess(baseObservable, apiClient);
}

// Mock GoogleApiClient connection success behaviour
protected <T> void setupBaseObservableSuccess(final BaseObservable<T> baseObservable, final GoogleApiClient apiClient) {
doAnswer(invocation -> {
final Subscriber<? super T> subscriber = ((BaseObservable.ApiClientConnectionCallbacks)invocation.getArguments()[0]).subscriber;

doAnswer(invocation1 -> {
baseObservable.onGoogleApiClientReady(apiClient, subscriber);
return null;
}).when(apiClient).connect();

return apiClient;
}).when(baseObservable).createApiClient(Matchers.any(BaseRx.ApiClientConnectionCallbacks.class));
}

// Mock GoogleApiClient resolution behaviour
protected <T> void setupBaseObservableResolution(final BaseObservable<T> baseObservable, final GoogleApiClient apiClient) {
doAnswer(invocation -> {
doAnswer(invocation1 -> {
try {
final Field observableSetField = BaseRx.class.getDeclaredField("observableSet");
observableSetField.setAccessible(true);
((Set<BaseRx>)observableSetField.get(baseObservable)).add(baseObservable);
} catch(Exception e) { }
return null;
}).when(apiClient).connect();

return apiClient;
}).when(baseObservable).createApiClient(Matchers.any(BaseRx.ApiClientConnectionCallbacks.class));
}

// Mock GoogleApiClient connection success behaviour
protected <T> void setupBaseSingleSuccess(final BaseSingle<T> baseSingle) {
setupBaseSingleSuccess(baseSingle, apiClient);
}

// Mock GoogleApiClient connection success behaviour
protected <T> void setupBaseSingleSuccess(final BaseSingle<T> baseSingle, final GoogleApiClient apiClient) {
doAnswer(invocation -> {
final SingleSubscriber<? super T> subscriber = ((BaseSingle.ApiClientConnectionCallbacks)invocation.getArguments()[0]).subscriber;

doAnswer(invocation1 -> {
baseSingle.onGoogleApiClientReady(apiClient, subscriber);
return null;
}).when(apiClient).connect();

return apiClient;
}).when(baseSingle).createApiClient(Matchers.any(BaseRx.ApiClientConnectionCallbacks.class));
}

// Mock GoogleApiClient connection error behaviour
protected <T> void setupBaseObservableError(final BaseObservable<T> baseObservable) {
doAnswer(invocation -> {
final Subscriber<? super T> subscriber = ((BaseObservable.ApiClientConnectionCallbacks)invocation.getArguments()[0]).subscriber;

doAnswer(invocation1 -> {
subscriber.onError(new GoogleAPIConnectionException("Error connecting to GoogleApiClient.", connectionResult));
return null;
}).when(apiClient).connect();

return apiClient;
}).when(baseObservable).createApiClient(Matchers.any(BaseRx.ApiClientConnectionCallbacks.class));
}

// Mock GoogleApiClient connection error behaviour
protected <T> void setupBaseSingleError(final BaseSingle<T> baseSingle) {
doAnswer(invocation -> {
final SingleSubscriber<? super T> subscriber = ((BaseSingle.ApiClientConnectionCallbacks)invocation.getArguments()[0]).subscriber;

doAnswer(invocation1 -> {
subscriber.onError(new GoogleAPIConnectionException("Error connecting to GoogleApiClient.", connectionResult));
return null;
}).when(apiClient).connect();

return apiClient;
}).when(baseSingle).createApiClient(Matchers.any(BaseRx.ApiClientConnectionCallbacks.class));
}

@SuppressWarnings("unchecked")
protected void setPendingResultValue(final Result result) {
doAnswer(invocation -> {
((ResultCallback)invocation.getArguments()[0]).onResult(result);
return null;
}).when(pendingResult).setResultCallback(Matchers.<ResultCallback>any());
}

protected static void assertError(TestSubscriber sub, Class<? extends Throwable> errorClass) {
sub.assertError(errorClass);
sub.assertNoValues();
sub.assertUnsubscribed();
}

@SuppressWarnings("unchecked")
protected static void assertSingleValue(TestSubscriber sub, Object value) {
sub.assertCompleted();
sub.assertUnsubscribed();
sub.assertValue(value);
}

protected static void assertNoValue(TestSubscriber sub) {
sub.assertCompleted();
sub.assertUnsubscribed();
sub.assertNoValues();
}
}
79 changes: 79 additions & 0 deletions library/src/test/java/com/patloew/rxwear/BaseRxTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package com.patloew.rxwear;

import android.support.v4.content.ContextCompat;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.common.api.Scope;
import com.google.android.gms.common.api.Status;
import com.google.android.gms.wearable.Wearable;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Matchers;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.powermock.core.classloader.annotations.PrepareOnlyThisForTest;
import org.powermock.core.classloader.annotations.SuppressStaticInitializationFor;
import org.powermock.modules.junit4.PowerMockRunner;

import static junit.framework.Assert.assertEquals;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;

@RunWith(PowerMockRunner.class)
@PrepareOnlyThisForTest({ ContextCompat.class, Wearable.class, Status.class, ConnectionResult.class, GoogleApiClient.Builder.class })
@SuppressStaticInitializationFor("com.google.android.gms.wearable.Wearable")
public class BaseRxTest extends BaseOnSubscribeTest {

@Before
public void setup() throws Exception {
MockitoAnnotations.initMocks(this);
super.setup();
}

@Test
public void setupFitnessPendingResult_NoTimeout() {
BaseRx<Object> baseRx = spy(new BaseRx<Object>(rxWear, null, null) { });

ResultCallback resultCallback = Mockito.mock(ResultCallback.class);

baseRx.setupWearPendingResult(pendingResult, resultCallback);

verify(pendingResult).setResultCallback(resultCallback);
}

@Test
public void setupFitnessPendingResult_Timeout() {
BaseRx<Object> baseRx = spy(new BaseRx<Object>(rxWear, TIMEOUT_TIME, TIMEOUT_TIMEUNIT) { });

ResultCallback resultCallback = Mockito.mock(ResultCallback.class);

baseRx.setupWearPendingResult(pendingResult, resultCallback);

verify(pendingResult).setResultCallback(resultCallback, TIMEOUT_TIME, TIMEOUT_TIMEUNIT);
}

@Test
public void createApiClient() {
GoogleApiClient.Builder builder = Mockito.mock(GoogleApiClient.Builder.class);

BaseRx<Object> baseRx = spy(new BaseRx<Object>(rxWear, null, null) { });

doReturn(builder).when(baseRx).getApiClientBuilder();
doReturn(apiClient).when(builder).build();

BaseRx.ApiClientConnectionCallbacks callbacks = Mockito.mock(BaseRx.ApiClientConnectionCallbacks.class);

assertEquals(apiClient, baseRx.createApiClient(callbacks));
verify(builder).addApi(Wearable.API);
verify(builder).addConnectionCallbacks(callbacks);
verify(builder).addOnConnectionFailedListener(callbacks);
verify(builder, never()).addScope(Matchers.any(Scope.class));
verify(callbacks).setClient(Matchers.any(GoogleApiClient.class));
}
}
Loading

0 comments on commit f552cec

Please sign in to comment.