Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
CustomTestRunner (Robolectric 2.x) and Crashlytics shadow class
package com.example;
import com.example.shadows.ShadowCrashlytics;
import org.junit.runners.model.InitializationError;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.bytecode.ClassInfo;
import org.robolectric.bytecode.Setup;
import org.robolectric.bytecode.ShadowMap;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
* Custom unit test runner. Enables custom shadows for testing third party library integrations.
* <p />
* <strong>Adding a Custom Shadow</strong>
* <ol>
* <li>Create a new custom shadow class using instructions outlined here:
* <li>Map the shadow class to the original using
* {@link org.robolectric.annotation.Implements}.</li>
* <li>Customize behavior of the shadow using
* {@link org.robolectric.annotation.Implementation}.</li>
* <li>Add the original class name to the {@link #CUSTOM_SHADOW_TARGETS} list.</li>
* <li>Bind the shadow class by calling {@link ShadowMap.Builder#addShadowClass(Class)} in
* {@link #createShadowMap()}.</li>
* <li>Be sure to use {@code @RunWith(CustomTestRunner.class)} at the top of your tests.</li>
* </ol>
public class CustomTestRunner extends RobolectricTestRunner {
* List of fully qualified class names backed by custom shadows in the test harness.
private static final List<String> CUSTOM_SHADOW_TARGETS =
public CustomTestRunner(Class<?> testClass) throws InitializationError {
* Adds custom shadow classes to Robolectric shadow map.
protected ShadowMap createShadowMap() {
return super.createShadowMap()
* Replaces Robolectric {@link Setup} with {@link CustomSetup} subclass.
public Setup createSetup() {
return new CustomSetup();
* Modified Robolectric {@link Setup} that instruments third party classes with custom shadows.
public class CustomSetup extends Setup {
public boolean shouldInstrument(ClassInfo classInfo) {
return CUSTOM_SHADOW_TARGETS.contains(classInfo.getName())
|| super.shouldInstrument(classInfo);
package com.example.shadows;
import android.content.Context;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
* Custom shadow implementation for {@link}.
public class ShadowCrashlytics {
private static Context context = null;
private static String userIdentifier = null;
public static void start(Context context) {
ShadowCrashlytics.context = context;
public static void setUserIdentifier(String identifier) {
userIdentifier = identifier;
public static Context getContext() {
return context;
public static String getUserIdentifier() {
return userIdentifier;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.