I have a View that includes an instance of android.support.v7.app.MediaRouteButton
in its layout.
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="mykwillis.com.mediaroutebutton.MainActivity">
<android.support.v7.app.MediaRouteButton
android:id="@+id/video_layer_chromecast_button"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"/>
</android.support.constraint.ConstraintLayout>
I've created the beginning of a basic Robolectric test that does nothing more than build and create the MainActivity:
@RunWith(RobolectricTestRunner.class)
@Config(constants = BuildConfig.class)
public class MainActivityTest {
@Test
public void loadActivity() {
MainActivity activity = Robolectric.buildActivity(MainActivity.class).create().get();
}
}
When I try to run this test, I receive the following error:
android.view.InflateException: XML file build/intermediates/res/merged/debug/layout/activity_main.xml line #-1 (sorry, not yet implemented): XML file build/intermediates/res/merged/debug/layout/activity_main.xml line #-1 (sorry, not yet implemented): Error inflating class android.support.v7.app.MediaRouteButton
Caused by: android.view.InflateException: XML file build/intermediates/res/merged/debug/layout/activity_main.xml line #-1 (sorry, not yet implemented): Error inflating class android.support.v7.app.MediaRouteButton
Digging in deeper, it appears that Robolectric is failing when it tries to load the style information for MediaRouteButton. The relevant stack trace seems to be this:
Caused by: java.lang.ClassCastException: org.robolectric.res.AttrData cannot be cast to org.robolectric.res.StyleData at
org.robolectric.shadows.ShadowAssetManager.resolveStyle(ShadowAssetManager.java:617) at
org.robolectric.shadows.ShadowAssetManager.buildTypedValue(ShadowAssetManager.java:742) at
org.robolectric.shadows.ShadowAssetManager.attrsToTypedArray(ShadowAssetManager.java:793) at
org.robolectric.shadows.ShadowResourcesImpl$ShadowThemeImpl.obtainStyledAttributes(ShadowResourcesImpl.java:177) at android.content.res.ResourcesImpl$ThemeImpl.obtainStyledAttributes(ResourcesImpl.java) at
android.content.res.Resources$Theme.obtainStyledAttributes(Resources.java:1440) at android.content.Context.obtainStyledAttributes(Context.java:587) at
android.support.v7.app.MediaRouterThemeHelper.getThemeColor(MediaRouterThemeHelper.java:169) at
android.support.v7.app.MediaRouterThemeHelper.getControllerColor(MediaRouterThemeHelper.java:94) at
android.support.v7.app.MediaRouterThemeHelper.createThemedContext(MediaRouterThemeHelper.java:62) at android.support.v7.app.MediaRouteButton.(MediaRouteButton.java) at
android.view.LayoutInflater.createView(LayoutInflater.java:645)
I am using the following dependencies:
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:25.3.0'
compile 'com.android.support:mediarouter-v7:25.3.0'
compile 'com.android.support.constraint:constraint-layout:1.0.2'
testCompile 'junit:junit:4.12'
testCompile "org.robolectric:robolectric:3.3.1"
testCompile 'org.khronos:opengl-api:gl1.1-android-2.1_r1' // https://github.com/robolectric/robolectric/issues/1932
}
I assume that this means I am out of luck with regard to Robolectric providing a Shadow for MediaRouteButton
(provided by com.android.support:mediarouter-v7:25.3.0), and that I need to create a Shadow for this class myself. I followed the guide at http://robolectric.org/extending/ in an attempt to create a simple shadow that would at least allow my view to load, but to no avail. Here's what I created:
@Implements(android.support.v7.app.MediaRouteButton.class)
public class MediaRouteButtonShadow extends ShadowView {
public void __constructor__(Context context, AttributeSet attributeSet, int defStyle) {
}
}
And then I updated my @Config
statement to be:
@Config(constants = BuildConfig.class, shadows = MediaRouteButtonShadow.class)
Unfortunately, I get the same error with this configuration.
Any pointers on how to create a minimal Shadow that will allow the view to load?
Update: a sample application demonstrating the problem is here: https://github.com/mykwillis/android-mediaroutebutton-test
This issue, tracked here, has been resolved using new functionality in Robolectric version 4.0.
Update dependencies and add a testOptions
section to build.gradle:
dependencies {
// ...
testCompile "org.robolectric:robolectric:4.0"
}
testOptions {
unitTests {
includeAndroidResources = true
}
}
and add this line to gradle.properties:
enableUnitTestBinaryResources=true
Also make sure you've updated to the latest gradle plugin.