5

I'm using Robolectric 3.3 to test AppCompatActivity from com.android.support:appcompat-v7:23.4.0
After I got:

java.lang.IllegalStateException: You need to use a Theme.AppCompat theme (or descendant) with this activity.

I created the following test runner:

public class ActivityTestRunner extends RobolectricTestRunner {

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

    @Override
    protected AndroidManifest getAppManifest(Config config)
    {
        return new AppManifest(Fs.fileFromPath(config.manifest()),
                Fs.fileFromPath(config.resourceDir()),
                Fs.fileFromPath(config.assetDir()));
    }

    private class AppManifest extends AndroidManifest
    {
        private static final String THEME = "@style/Theme.AppCompat";


        public AppManifest(FsFile androidManifestFile, FsFile resDirectory, FsFile assetsDirectory) {
            super(androidManifestFile, resDirectory, assetsDirectory);
        }

        public AppManifest(FsFile androidManifestFile, FsFile resDirectory, FsFile assetsDirectory, String overridePackageName) {
            super(androidManifestFile, resDirectory, assetsDirectory, overridePackageName);
        }

        @Override
        public String getThemeRef() {
            return THEME;
        }

        @Override
        public String getThemeRef(String activityClassName) {
            return THEME;
        }
    }
}

And then I'm getting:

java.lang.NullPointerException
    at org.robolectric.res.ThemeStyleSet$OverlayedStyle.equals(ThemeStyleSet.java:67)
    at org.robolectric.res.ThemeStyleSet.apply(ThemeStyleSet.java:29)
    at org.robolectric.shadows.ShadowAssetManager.applyThemeStyle(ShadowAssetManager.java:595)
    at org.robolectric.shadows.ShadowAssetManager.applyThemeStyle(ShadowAssetManager.java:588)
    at android.content.res.AssetManager.applyThemeStyle(AssetManager.java)
    at android.content.res.Resources$Theme.applyStyle(Resources.java:1104)
    at android.view.ContextThemeWrapper.onApplyThemeResource(ContextThemeWrapper.java:132)
    at android.app.Activity.onApplyThemeResource(Activity.java:3307)
    at android.view.ContextThemeWrapper.initializeTheme(ContextThemeWrapper.java:144)
    at android.view.ContextThemeWrapper.setTheme(ContextThemeWrapper.java:89)
    at android.support.v7.app.AppCompatActivity.setTheme(AppCompatActivity.java:90)
    at org.robolectric.shadows.ShadowActivity.setThemeFromManifest(ShadowActivity.java:89)
    at org.robolectric.shadows.CoreShadowsAdapter$1.setThemeFromManifest(CoreShadowsAdapter.java:30)
    at org.robolectric.android.controller.ActivityController.attach(ActivityController.java:84)
    at org.robolectric.android.controller.ActivityController.of(ActivityController.java:34)
    at org.robolectric.Robolectric.buildActivity(Robolectric.java:93)
    at org.robolectric.Robolectric.buildActivity(Robolectric.java:89)
    at org.robolectric.Robolectric.setupActivity(Robolectric.java:97)
    at com.lacoon.components.activities.MainActivityTest.setUp(MainActivityTest.java:35)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24)
    at org.robolectric.internal.SandboxTestRunner$2.evaluate(SandboxTestRunner.java:209)
    at org.robolectric.internal.SandboxTestRunner.runChild(SandboxTestRunner.java:109)
    at org.robolectric.internal.SandboxTestRunner.runChild(SandboxTestRunner.java:36)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.robolectric.internal.SandboxTestRunner$1.evaluate(SandboxTestRunner.java:63)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:117)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:42)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:262)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:84)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)

Style:

<style name="AppTheme" parent="Theme.AppCompat">
        <!-- Customize your theme here. -->
        <item name="windowActionBar">false</item>
        <item name="windowNoTitle">true</item>
        <item name="android:textColor">@color/white</item>
        <item name="colorPrimary">@color/main_background</item>
        <item name="colorPrimaryDark">@color/main_background</item>
        <item name="android:textViewStyle">@style/RobotoLightTextViewStyle</item>"
        <item name="colorAccent">@color/check_point_pink</item>
        <item name="colorControlNormal">#9a9a9a</item>
        <item name="colorControlActivated">@color/check_point_pink</item>
        <!--<item name="editTextStyle">@style/welcome_editbox</item>-->
        <!--<item name="alertDialogStyle">@style/dialog_theme</item>-->
    </style>

onCreate:

@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.main_activity);
        getMainScreenFragment();
        mToolbar = (Toolbar) findViewById(toolbar);
        setUpToolBar();
    }

How to make it work?

NickF
  • 5,637
  • 12
  • 44
  • 75

4 Answers4

2

For me, what fixed the issue was adding the following to my app gradle file

android {
   //OTHER CONFIG

   testOptions {
    unitTests {
        includeAndroidResources = true
    }
}


}
Akinola Olayinka
  • 841
  • 7
  • 11
1

Just remove your custom runner and fix path for the Robolectric test. Check how to do it here.

Eugen Martynov
  • 19,888
  • 10
  • 61
  • 114
1

The problem was that I didn't add @Config(constants = BuildConfig.class)
Which must be added in the tutorial

NickF
  • 5,637
  • 12
  • 44
  • 75
-2

The reason you are having this problem is because the activity you are trying to apply the dialog theme to is extending ActionBarActivity which requires the AppCompat theme to be applied.

Update: Extending AppCompatActivity would also have this problem

In this case, change the Java inheritance from ActionBarActivity to Activity and leave the dialog theme in the manifest as it is, a non Theme.AppCompat value

The general rule is that if you want your code to support older versions of Android, it should have the AppCompat theme and the java code should extend AppCompatActivity. If you have *an activity that doesn't need this support, such as you only care about the latest versions and features of Android, you can apply any theme to it but the java code must extend plain old Activity.

NOTE: When change from AppCompatActivity (or a subclass, ActionBarActivity), to Activity, must also change the various calls with "support" to the corresponding call without "support". So, instead of getSupportFragmentManager, call getFragmentManager.

https://stackoverflow.com/a/21815015/8148100

Mahesh Lad
  • 1,997
  • 1
  • 9
  • 8