Question

I've a View with a custom theme as explained here and that solves the issue described but causes the following error when i call visible() on ActivityController.

android.content.res.Resources$NotFoundException: Resource ID #0x7f0c0000
at android.content.res.Resources.getValue(Resources.java:1118)
at android.content.res.Resources.loadXmlResourceParser(Resources.java:2304)
at android.content.res.Resources.getLayout(Resources.java:934)
at android.support.v7.internal.view.SupportMenuInflater.inflate(SupportMenuInflater.java:115)
at com.myCompany.myApp.activities.LogActivity.onCreateOptionsMenu(LogActivity.java:36)
at android.app.Activity.onCreatePanelMenu(Activity.java:2504)
at android.support.v4.app.FragmentActivity.onCreatePanelMenu(FragmentActivity.java:224)
at android.support.v7.app.ActionBarActivity.superOnCreatePanelMenu(ActionBarActivity.java:232)
at android.support.v7.app.ActionBarActivityDelegateICS.onCreatePanelMenu(ActionBarActivityDelegateICS.java:147)
at android.support.v7.app.ActionBarActivity.onCreatePanelMenu(ActionBarActivity.java:199)
at android.support.v7.app.ActionBarActivityDelegateICS$WindowCallbackWrapper.onCreatePanelMenu(ActionBarActivityDelegateICS.java:285)
at com.android.internal.policy.impl.PhoneWindow.preparePanel(PhoneWindow.java:413)
at com.android.internal.policy.impl.PhoneWindow.doInvalidatePanelMenu(PhoneWindow.java:775)
at com.android.internal.policy.impl.PhoneWindow$1.run(PhoneWindow.java:198)
at org.robolectric.util.Scheduler.postDelayed(Scheduler.java:37)
at org.robolectric.shadows.ShadowLooper.post(ShadowLooper.java:207)
at org.robolectric.shadows.ShadowHandler.postDelayed(ShadowHandler.java:56)
at android.os.Handler.postDelayed(Handler.java)
at android.view.ViewRootImpl$RunQueue.executeActions(ViewRootImpl.java:6230)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1239)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1004)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5481)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:749)
at android.view.Choreographer.doCallbacks(Choreographer.java:562)
at android.view.Choreographer.doFrame(Choreographer.java:532)
at android.view.Choreographer$FrameHandler.handleMessage(Choreographer.java:664)
at org.robolectric.shadows.ShadowHandler.routeMessage(ShadowHandler.java:125)
at org.robolectric.shadows.ShadowHandler.access$100(ShadowHandler.java:25)
at org.robolectric.shadows.ShadowHandler$1.run(ShadowHandler.java:110)
at org.robolectric.util.Scheduler$PostedRunnable.run(Scheduler.java:162)
at org.robolectric.util.Scheduler.runOneTask(Scheduler.java:107)
at org.robolectric.util.Scheduler.advanceTo(Scheduler.java:92)
at org.robolectric.util.Scheduler.advanceToLastPostedRunnable(Scheduler.java:68)
at org.robolectric.util.Scheduler.unPause(Scheduler.java:25)
at org.robolectric.shadows.ShadowLooper.unPause(ShadowLooper.java:228)
at org.robolectric.shadows.ShadowLooper.runPaused(ShadowLooper.java:267)
at org.robolectric.util.ActivityController.visible(ActivityController.java:201)
at com.myCompany.myApp.test.activities.LogActivityTest.setUp(LogActivityTest.java:50)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24)
at org.robolectric.RobolectricTestRunner$2.evaluate(RobolectricTestRunner.java:230)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.robolectric.RobolectricTestRunner$1.evaluate(RobolectricTestRunner.java:172)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)

Here is the syle.xml file which contains the custom theme

<!--
    Base application theme, dependent on API level. This theme is replaced
    by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
-->
<style name="AppBaseTheme" parent="android:Theme.Light">
    <!--
        Theme customizations available in newer API levels can go in
        res/values-vXX/styles.xml, while customizations related to
        backward-compatibility can go here.
    -->
</style>

<!-- Application theme. -->
<style name="AppTheme" parent="AppBaseTheme">
    <!-- All customizations that are NOT specific to a particular API-level can go here. -->
</style>

<style name="Theme.RobolectricCompatible" parent="@style/Theme.Base.AppCompat.Light.DarkActionBar">
    <item name="android:windowNoTitle">false</item>
</style>

and this is the activity block in which I set the theme

<activity
        android:name=".activities.LogActivity"
        android:label="@string/log_activity_title"
        android:parentActivityName="com.myApp.activities.MainActivity"
        android:theme="@style/Theme.RobolectricCompatible" >
        <meta-data
            android:name="android.support.PARENT_ACTIVITY"
        android:value="com.myApp.activities.MainActivity" />
</activity>

I've another Activity which uses Theme.Base.AppCompat.Light.DarkActionBar theme and I can test it correctly, but if I change the theme to Theme.RobolectricCompatible it shows the same behavior.

Finally this is what Eclipse output when I run the tests:

    DEBUG: Loading resources for com.myCompany.myApp from C:\Users\luca\Android\myAppTest\..\myApp\res...
    DEBUG: Loading resources for android.support.v7.appcompat from C:\Users\luca\Android\myAppTest\..\myApp\..\android-support-v7-appcompat\res...
    DEBUG: Loading resources for android from jar:C:\Users\luca\.m2\repository\org\robolectric\android-all\4.3_r2-robolectric-0\android-all-4.3_r2-robolectric-0.jar!/res...

Please note that the paths point to the right res directories.

Without calling visible() I don't get any error but I need to test some menuItem s which are initialized inside onCreateOptionsMenu() which, in turn, is called inside visible() ( I've already tried to call the method by myself passing a TestMenu object but it didn't work (and is also deprecated))

I'm using robolectric 2.2 but I've also tried with 2.3-SNAPSHOT

I'd really appreciate any help because I've run out of ideas.

Was it helpful?

Solution

The problem is because you use support library and robolectric is not compatible with it. The same happens with ActionBarSherlock.

Luckily the problem has already it's solution. This worked for me.

According to sneuberger-amazon's post on https://github.com/robolectric/robolectric/issues/:

The problem is that Robolectric provides a ShadowMenuInflater, but it does not provide a ShadowSupportMenuInflater (which is what appcompat uses).

You can fix this by creating a org.robolectric.shadows.ShadowSupportMenuInflater class with contents:

package org.robolectric.shadows;

import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;

import android.support.v7.internal.view.SupportMenuInflater;
import android.view.Menu;

@Implements(SupportMenuInflater.class)
public class ShadowSupportMenuInflater extends ShadowMenuInflater {
    @Implementation
    public void inflate(int menuRes, Menu menu) {
        super.inflate(menuRes, menu);
    }
}

Put this class in your own project's org.robolectric.shadows package. That way Robolectric will find it when looking for a shadow for SupportMenuInflater, so that all your tests will get it automatically (no need to add a shadow Config to every test).

OTHER TIPS

With Robolectric 2.3, try annotating your test class with

@Config(qualifiers = "v10")
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top