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?