Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android Lollipop Appcompat problems running with Robolectric

I'm not able to run Robolectic test when using new Appcompat support library available since Android Lollipop came out. I've followed:

  • https://github.com/robolectric/deckard-gradle
  • https://chris.banes.me/2014/10/17/appcompat-v21/

My current progress is available here: https://github.com/fada21/android-tdd-bootstrap

My configuration (distilled) is:

android {
  compileSdkVersion 21
  buildToolsVersion "21.0.1"

defaultConfig {
  applicationId "com.fada21.android.bootstrap"
  minSdkVersion 15
  targetSdkVersion 21

...

dependencies {
  compile fileTree(dir: 'libs', include: ['*.jar'])
  compile 'com.android.support:support-v4:21.0.0'
  compile 'com.android.support:appcompat-v7:21.0.0'

...

androidTestCompile('org.robolectric:robolectric:2.4-SNAPSHOT') {

I've raised an issue here: https://github.com/robolectric/robolectric/issues/1332 (look here for more details).

This is errors I'm getting:

java.lang.RuntimeException: Could not find any resource  from reference ResName{com.fada21.android.bootstrap:style/Theme_AppCompat_Light_NoActionBar} from style StyleData{name='AppTheme', parent='Theme_AppCompat_Light_NoActionBar'} with theme null
at org.robolectric.shadows.ShadowAssetManager$StyleResolver.getParent(ShadowAssetManager.java:456)
at org.robolectric.shadows.ShadowAssetManager$StyleResolver.getAttrValue(ShadowAssetManager.java:394)
at org.robolectric.shadows.ShadowResources.getOverlayedThemeValue(ShadowResources.java:297)
at org.robolectric.shadows.ShadowResources.findAttributeValue(ShadowResources.java:286)
at org.robolectric.shadows.ShadowResources.attrsToTypedArray(ShadowResources.java:189)
at org.robolectric.shadows.ShadowResources.access$000(ShadowResources.java:48)
at org.robolectric.shadows.ShadowResources$ShadowTheme.obtainStyledAttributes(ShadowResources.java:494)
at org.robolectric.shadows.ShadowResources$ShadowTheme.obtainStyledAttributes(ShadowResources.java:489)
at org.robolectric.shadows.ShadowResources$ShadowTheme.obtainStyledAttributes(ShadowResources.java:484)
at android.content.res.Resources$Theme.obtainStyledAttributes(Resources.java)
at android.content.Context.obtainStyledAttributes(Context.java:380)
at android.support.v7.app.ActionBarActivityDelegate.onCreate(ActionBarActivityDelegate.java:143)
at android.support.v7.app.ActionBarActivityDelegateBase.onCreate(ActionBarActivityDelegateBase.java:139)
at android.support.v7.app.ActionBarActivity.onCreate(ActionBarActivity.java:123)
at com.fada21.android.bootstrap.HomeActivity.onCreate(HomeActivity.java:28)
at android.app.Activity.performCreate(Activity.java:5133)
at org.fest.reflect.method.Invoker.invoke(Invoker.java:112)
at org.robolectric.util.ActivityController$1.run(ActivityController.java:113)
at org.robolectric.shadows.ShadowLooper.runPaused(ShadowLooper.java:265)
at org.robolectric.util.ActivityController.create(ActivityController.java:110)
at org.robolectric.util.ActivityController.create(ActivityController.java:120)
at com.fada21.android.bootstrap.HomeActivityTest.testActivityNotNull(HomeActivityTest.java:24)
like image 232
fada21 Avatar asked Oct 22 '14 16:10

fada21


1 Answers

NOTE: As of 7/7/15, Roboelectric 3.0 has been released. It solves the problem in question making this answer no longer necessary.

Old Answer:

Until Robolectric 3.0 comes out, here's a fix.

#/app/src/main/res/values/styles.xml
<resources>

    //<!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        //<!-- Customize your theme here. -->
    </style>


    //<!-- Hack for Robolectric to run with appcompat.v7 -->
    <style name="RoboAppTheme" parent="@android:style/Theme.Holo.Light.DarkActionBar">
        //<!-- Customize your theme here. -->
    </style>

</resources>

And then adjust your custom RobolectricRunner class

public class MyRobolectricTestRunner extends RobolectricTestRunner {
    private static final int MAX_SDK_SUPPORTED_BY_ROBOLECTRIC = 18;

    public MyRobolectricTestRunner(Class<?> testClass) throws InitializationError {
        super(testClass);
    }

    @Override
    protected AndroidManifest getAppManifest(Config config) {
        String manifestProperty = "../app/src/main/AndroidManifest.xml";
        String resProperty = "../app/src/main/res";
        return new AndroidManifest(Fs.fileFromPath(manifestProperty), Fs.fileFromPath(resProperty)) {
            @Override
            public int getTargetSdkVersion() {
                return MAX_SDK_SUPPORTED_BY_ROBOLECTRIC;
            }

            @Override
            public String getThemeRef(Class<? extends Activity> activityClass) {
                return "@style/RoboAppTheme";
            }
        };
    }
}

Basically we are just telling the JVM to use a different app theme. Then use this TestRunner like you normally would with @RunWith(MyRobolectricTestRunner.class).

Note: This addresses activities that only extend Activity, other issues of the same type occur for activities that extend ActionBarActivity

EDIT: As of 4/7/15, Robolectric 3.0-snapshot build is available which accounts for ActionBarActivity. More information is available in the links in the comments

like image 199
dsrees Avatar answered Sep 27 '22 21:09

dsrees