Android Lollipop Appcompat problems running with Robolectric

笑着哭i 提交于 2019-12-03 03:16:49

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

Add a project.properties file at the same hierarki level as your manifest, with the following content:

android.library.reference.1=../../build/intermediates/exploded-aar/com.android.support/appcompat-v7/22.0.0

Make sure the appcompat version is the same as in your gradle file.

Using this custom RobolectricTestRunner fixed a similar problem that I was having. This also means you don't need @Config(emulateSdk = 18) in every test.

Replace: @RunWith(RobolectricTestRunner.class)

with: @RunWith(MyRobolectricTestRunner.class) in all your Robolectric tests

public class MyRobolectricTestRunner extends RobolectricTestRunner {

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

    @Override
    protected AndroidManifest getAppManifest(Config config) {
        String manifestProperty = System.getProperty("android.manifest");
        if (config.manifest().equals(Config.DEFAULT) && manifestProperty != null) {
            String resProperty = System.getProperty("android.resources");
            String assetsProperty = System.getProperty("android.assets");
            CustomAndroidManifest androidManifest = new CustomAndroidManifest(
                    Fs.fileFromPath(manifestProperty),
                    Fs.fileFromPath(resProperty),
                    Fs.fileFromPath(assetsProperty));
            androidManifest.setPackageName("com.justyoyo");
            return androidManifest;
        }
        return super.getAppManifest(config);
    }

    private static class CustomAndroidManifest extends AndroidManifest {

        private static final int MAX_SDK_SUPPORTED_BY_ROBOLECTRIC = 18;

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

        @Override
        public int getTargetSdkVersion() {
            return MAX_SDK_SUPPORTED_BY_ROBOLECTRIC;
        }
    }
}

Credit to this: https://github.com/robolectric/robolectric/issues/1025

some solution could be:

add to the test:
@Config(emulateSdk = 18, reportSdk = 18)

and make it something like:

@RunWith(RobolectricTestRunner.class)
@Config(emulateSdk = 18, reportSdk = 18)
public class YourClassTestNameTest {…
Csbaek000
@RunWith(RobolectricGradleTestRunner.class)
@Config(constants = BuildConfig.class, sdk = 21)

solved my issue.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!