11

So this is a possible duplicate of this question: Testing custom Views with Robolectric But since that one doesn't have an accepted answer, I'm going to ask again, with my own code examples. I'm using Robolectric 2.3 to run unit tests on a project which uses a custom view defined in a file called "here_now.xml" as:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
           android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:orientation="vertical"
           android:weightSum="1">

           <me.ambient.meetup.swiper.SwipeListView
                xmlns:swipe="http://schemas.android.com/apk/res-auto"
                android:id="@+id/nearbyPeopleList"
                android:listSelector="#00000000"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                swipe:swipeFrontView="@+id/user_profile_layout"
                swipe:swipeBackView="@+id/user_profile_bg"
                swipe:swipeDrawableChecked="@drawable/plus"
                swipe:swipeDrawableUnchecked="@drawable/minus"
                swipe:swipeCloseAllItemsWhenMoveList="true"
                swipe:swipeMode="both"/>

    </LinearLayout>

That 'SwipeListView' is a custom view and it has those custom XML attributes. Now, this compiles and runs okay on the app. But when running Robolectric tests involving the parent activity that instantiates that view, I run into inflation errors:

me.ambient.meetup.test.HereNowActivityTest > testEditProfileMenuButton FAILED
    android.view.InflateException: XML file /Users/shayak/Documents/SourceCode/MagnetAndroid/magnet-android/meetup/src/main/res/layout/here_now.xml line #-1 (sorry, not yet implemented): Error inflating class me.ambient.meetup.swiper.SwipeListView
        at android.view.LayoutInflater.createView(LayoutInflater.java:620)
        at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:696)
        at android.view.LayoutInflater.rInflate(LayoutInflater.java:755)
        at android.view.LayoutInflater.rInflate(LayoutInflater.java:758)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:492)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:397)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:353)
        at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:267)
        at android.app.Activity.setContentView(Activity.java:1895)
        at me.ambient.meetup.HereNowActivity.init(HereNowActivity.scala:93)
        at me.ambient.meetup.HereNowActivity.onCreate(HereNowActivity.scala:34)
        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 me.ambient.meetup.test.HereNowActivityTest.testEditProfileMenuButton(HereNowActivityTest.scala:25)

        Caused by:
        java.lang.reflect.InvocationTargetException
            at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
            at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
            at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
            at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
            at android.view.LayoutInflater.$$robo$$LayoutInflater_1d1f_createView(LayoutInflater.java:594)
            at android.view.LayoutInflater.createView(LayoutInflater.java)
            at android.view.LayoutInflater.$$robo$$LayoutInflater_1d1f_createViewFromTag(LayoutInflater.java:696)
            at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java)
            at android.view.LayoutInflater.$$robo$$LayoutInflater_1d1f_rInflate(LayoutInflater.java:755)
            at android.view.LayoutInflater.rInflate(LayoutInflater.java)
            at android.view.LayoutInflater.$$robo$$LayoutInflater_1d1f_rInflate(LayoutInflater.java:758)
            at android.view.LayoutInflater.rInflate(LayoutInflater.java)
            at android.view.LayoutInflater.$$robo$$LayoutInflater_1d1f_inflate(LayoutInflater.java:492)
            at android.view.LayoutInflater.inflate(LayoutInflater.java)
            at android.view.LayoutInflater.$$robo$$LayoutInflater_1d1f_inflate(LayoutInflater.java:397)
            at android.view.LayoutInflater.inflate(LayoutInflater.java)
            at android.view.LayoutInflater.$$robo$$LayoutInflater_1d1f_inflate(LayoutInflater.java:353)
            at android.view.LayoutInflater.inflate(LayoutInflater.java)
            at com.android.internal.policy.impl.PhoneWindow.$$robo$$PhoneWindow_1a87_setContentView(PhoneWindow.java:267)
            at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java)
            at android.app.Activity.$$robo$$Activity_c57b_setContentView(Activity.java:1895)
            at android.app.Activity.setContentView(Activity.java)
            at me.ambient.meetup.HereNowActivity.init(HereNowActivity.scala:93)
            at me.ambient.meetup.HereNowActivity.onCreate(HereNowActivity.scala:34)
            at android.app.Activity.$$robo$$Activity_c57b_performCreate(Activity.java:5133)
            at android.app.Activity.performCreate(Activity.java)
            at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
            at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
            at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
            at java.lang.reflect.Method.invoke(Method.java:597)
            ... 6 more

            Caused by:
            java.lang.RuntimeException: You forgot the attributes swipeFrontView or swipeBackView. You can add this attributes or use 'swipelist_frontview' and 'swipelist_backview' identifiers
                at me.ambient.meetup.swiper.SwipeListView.init(SwipeListView.java:211)
                at me.ambient.meetup.swiper.SwipeListView.<init>(SwipeListView.java:159)
                ... 36 more

I'll also put my Robolectric test here, which is in Scala FWIW:

@Config(manifest = "./src/main/AndroidManifest.xml")
@RunWith(classOf[RobolectricTestRunner])
class HereNowActivityTest extends Asserter with ThreadManipulator {

    @Test
    def testEditProfileMenuButton(): Unit = {
        val activity: HereNowActivity = Robolectric.buildActivity(classOf[HereNowActivity]).create().start().get()
        val editProfileItem = activity.findViewById(R.id.action_edit_profile).asInstanceOf[MenuItem]

        activity.onOptionsItemSelected(editProfileItem)

        val shadowActivity = Robolectric.shadowOf(activity)
        val startedIntent = shadowActivity.getNextStartedActivity()
        val shadowIntent = Robolectric.shadowOf(startedIntent)

        assertEquals(shadowIntent.getComponent().getClassName(), "me.ambient.meetup.EditProfileActivity")
    }
}

Does anyone know why I am unable to inflate a custom view when running Robolectric tests, as well as unable to set any of the custom attributes?

Community
  • 1
  • 1
ShayakB
  • 178
  • 8
  • Did you look into the error at the end of the stacktrace? `You forgot the attributes swipeFrontView or swipeBackView. You can add this attributes or use 'swipelist_frontview' and 'swipelist_backview' identifiers` It looks like it's your code that is crashing, not Robolectric – Alix Aug 31 '15 at 21:58
  • But if you check the XML code I pasted above, you can see I do have those attributes set, so I'm still confused – ShayakB Sep 01 '15 at 22:43
  • Yes, it looks odd. Put a breakpoint there and look at the state ? Maybe it will give you a hint – Alix Sep 02 '15 at 05:22
  • Found a solution? – Abubakar Jul 20 '18 at 13:21

0 Answers0