8

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

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)
Cœur
  • 37,241
  • 25
  • 195
  • 267
fada21
  • 3,188
  • 1
  • 22
  • 21
  • I'm currently following this thread https://github.com/robolectric/robolectric/issues/1332#issuecomment-61470450. Having the same issues. – loeschg Nov 03 '14 at 20:51
  • 1
    Yep, I started this thread. @loeschg Have you tried this ShadowSupportMenuInflater mentined in comment? – fada21 Nov 05 '14 at 23:18
  • I did try that... I think. I'm planning to take a focused look tomorrow. Thanks for pointing me that direction! – loeschg Nov 05 '14 at 23:23
  • 1
    I have been following this thread on github and here. Have you guys figured out a solution that works? I have the same thing and all my activities use the ActionBarActivity that tries to use the Theme.AppCompat.Light. The threads seem to point that it will be fixed in version 3.0. Have you guys found another way to test these activities with Robolectric? I have tried the answer here and a bunch of solutions in the github thread but no dice. – lazypig Jan 13 '15 at 01:01
  • @lazypig I've posted a solution. Could you give it a shot and tell me if that works for you? – dsrees Jan 28 '15 at 16:41
  • @drees thanks. Looks like hacky hack :p. Still vote up for effort. I'll confirm if have enough time for test solution. Still this solution looks to spaghetti and scary to rely on that when performing tests. To many moving parts IMHO. Do you know if Robolectric 3.0 will support API21 or at least 19 and appcompat? – fada21 Jan 28 '15 at 17:34
  • @lazypig if you'll be able to test drees's solution let me know what was your outcome. – fada21 Jan 28 '15 at 17:34
  • @fada21 yeah, I'm not completely happy with it either. I'm doing some further testing on the hack to see if it holds. Robo 3.0 should support API 21 but there isn't an expected release date on it. You can follow it [here](https://github.com/robolectric/robolectric/milestones). I think support is currently in the master branch, if you wanted to pull the project and compile it yourself into a .jar. That might work. I haven't tried it myself – dsrees Jan 28 '15 at 17:40
  • @fada21 What is the status of this? – Jared Burrows Aug 04 '15 at 21:13
  • @JaredBurrows I've accepted drees's answer, see below – fada21 Aug 06 '15 at 11:21

5 Answers5

13

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

dsrees
  • 6,116
  • 2
  • 26
  • 26
  • is there anything you can do for activities that extend from ActionBarActivity? All my activities extend from ActionBarActivity – ZakTaccardi Mar 28 '15 at 14:18
  • @ZakTaccardi I haven't dug into it enough to find out, I simply posted the solution that fixed my use case. You can try out [Robolectric 3.0-snapshot](https://github.com/robolectric/robolectric#using-snapshots) which I believe has support for ActionBarActivity? I'm not too sure. You'll have to do some more digging. Sorry. [Here is some more information](https://github.com/robolectric/robolectric/issues/1446) – dsrees Mar 29 '15 at 01:50
  • Robolectric 3.0 is the way to go if you still need Robolectic. I think using new android-testing library is better solution. – fada21 Aug 06 '15 at 11:16
  • 2
    I'm using 3.0 and still encountering this error, so if they had fixed it, the fix has been rolled back. – Mooing Duck May 08 '16 at 18:25
  • Yeah still seeing this on 3.4.2 – ocross Aug 08 '17 at 17:31
2

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.

Bolling
  • 3,954
  • 1
  • 27
  • 29
1

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

ajack
  • 586
  • 1
  • 5
  • 13
0

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 {…
cV2
  • 5,229
  • 3
  • 43
  • 53
  • I'm sorry man, I've just seen in your code, your crash is related to the full screen activity, I've seen some work arounds (possibly working) for that, like applying some parameter to the theme or use some other theme for this activity in test. Sorry currently on mobile. Good luck! Add some parts from stack traces to google like theme and app compact, I think you'll find something :) – cV2 Oct 28 '14 at 16:39
0
@RunWith(RobolectricGradleTestRunner.class)
@Config(constants = BuildConfig.class, sdk = 21)

solved my issue.

Nathan Tuggy
  • 2,237
  • 27
  • 30
  • 38
Csbaek000
  • 31
  • 6