Skip to content

Instantly share code, notes, and snippets.

@donnfelker
Last active July 19, 2016 10:42
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save donnfelker/8285289 to your computer and use it in GitHub Desktop.
Save donnfelker/8285289 to your computer and use it in GitHub Desktop.
ShadowTaskStackBuilder Blog Code
@Test
public void shouldBeAbleToGoToComments() {
Uri deepLink = Uri.parse("pfm:///user/frank/status/123/?version=88983845");
System.out.println(String.format("Testing %s", deepLink.toString()));
// The intent to start.
Intent expectedIntent = new Intent(Robolectric.application, Status.class);
expectedIntent.putExtra(Constants.Extras.STATUS_ID, 123L);
IntentCreator mockIntentCreator = mock(IntentCreator.class);
// Set up the stub
when(mockIntentCreator.newCommentsIntent(anyLong())).thenReturn(expectedIntent);
// Set up the router and run the code that will run the code path we want to test
DeepLinkRouterDouble router = DeepLinkRouterDouble.getInstance(Robolectric.application, Routes.class, new PfmDispatcher(Robolectric.application, mockIntentCreator), deepLink);
router.route();
// Assert that the intent returned goes to the welcome screen.
final Intent next = shadowOf(Robolectric.application).getNextStartedActivity();
ANDROID.assertThat(resolvedIntent).hasComponent(Robolectric.application, next);
ANDROID.assertThat(next).hasExtra(Constants.Extras.STATUS_ID);
// Verify that the intended intent creator method was indeed called.
verify(mockIntentCreator).newCommentsIntent(123L);
}
@RunWith(RobolectricTestRunner.class)
@Config(shadows = { ShadowTaskStackBuilder.class }) // Robolectric will read this and use the shadow for this test file
public class DeepLinkRouterTest
{
@Test
public void shouldBeAbleToGoToComments() {
Uri deepLink = Uri.parse("pfm:///user/frank/status/123/?version=88983845");
System.out.println(String.format("Testing %s", deepLink.toString()));
// The intent to start.
Intent expectedIntent = new Intent(Robolectric.application, Status.class);
expectedIntent.putExtra(Constants.Extras.STATUS_ID, 123L);
IntentCreator mockIntentCreator = mock(IntentCreator.class);
// Set up the stub
when(mockIntentCreator.newCommentsIntent(anyLong())).thenReturn(expectedIntent);
// Set up the router and run the code that will run the code path we want to test
DeepLinkRouterDouble router = DeepLinkRouterDouble.getInstance(Robolectric.application, Routes.class, new PfmDispatcher(Robolectric.application, mockIntentCreator), deepLink);
router.route();
// Assert that the intent returned goes to the welcome screen.
final Intent next = shadowOf(Robolectric.application).getNextStartedActivity();
ANDROID.assertThat(resolvedIntent).hasComponent(Robolectric.application, next);
ANDROID.assertThat(next).hasExtra(Constants.Extras.STATUS_ID);
// Verify that the intended intent creator method was indeed called.
verify(mockIntentCreator).newCommentsIntent(123L);
}
}
// Build the intent instance, etc
TaskStackBuilder t = TaskStackBuilder.create(context);
t.addNextIntentWithParentStack(intent);
t.startActivities();
package com.pfm.shadows;
import android.content.Context;
import android.content.Intent;
import android.support.v4.app.TaskStackBuilder;
import org.robolectric.Robolectric;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
import org.robolectric.annotation.RealObject;
import static org.robolectric.bytecode.ShadowWrangler.shadowOf;
import static org.robolectric.Robolectric.directlyOn;
/**
* This is kind of a hack, The real task stack builder walks the Android Manifest and then creates
* the various child activities. I have not taken the time to figure out if we can
* manually instantiate the activities or not. This is a simple fake routine to work around.
*/
@SuppressWarnings({"UnusedDeclaration"})
@Implements(TaskStackBuilder.class)
public class ShadowTaskStackBuilder
{
private Context context;
private Intent intent;
@RealObject
TaskStackBuilder realTaskStackBuilder;
private void setup(Context context) {
this.context = context;
}
@Implementation
public static TaskStackBuilder create(Context context) {
TaskStackBuilder taskStackBuilder = Robolectric.newInstanceOf(TaskStackBuilder.class);
ShadowTaskStackBuilder stsb = (ShadowTaskStackBuilder) shadowOf(taskStackBuilder);
stsb.setup(context);
return taskStackBuilder;
}
@Implementation
public TaskStackBuilder addNextIntentWithParentStack(Intent intent) {
this.intent = intent;
return realTaskStackBuilder;
}
@Implementation
public void startActivities() {
context.startActivity(intent);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment