Note that there are some explanatory texts on larger screens.

plurals
  1. POHow do I create a shadow class to work around crashes related to custom attributes when testing an Android app with Robolectric?
    primarykey
    data
    text
    <p>I'm integrating <a href="http://blog.sephiroth.it/2011/03/29/widget-slidingdrawer-top-to-bottom/" rel="nofollow noreferrer">a custom widget</a> into my project. It uses custom attributes and is crashing Robolectric. From what I gather, <a href="https://github.com/pivotal/robolectric/issues/285#issuecomment-7315793" rel="nofollow noreferrer">custom attributes aren't supported yet</a>. Note: the constructor is "hostile" because it throws exceptions on construction, but I've commented them out for now.</p> <p><strong>Crash Log</strong></p> <blockquote> <p>java.lang.RuntimeException: error inflating layout/main at com.xtremelabs.robolectric.res.ViewLoader.inflateView(ViewLoader.java:106) at com.xtremelabs.robolectric.res.ViewLoader.inflateView(ViewLoader.java:82) at com.xtremelabs.robolectric.res.ViewLoader.inflateView(ViewLoader.java:86) at com.xtremelabs.robolectric.res.ResourceLoader.inflateView(ResourceLoader.java:377) at com.xtremelabs.robolectric.shadows.ShadowLayoutInflater.inflate(ShadowLayoutInflater.java:43) at com.xtremelabs.robolectric.shadows.ShadowLayoutInflater.inflate(ShadowLayoutInflater.java:48) at android.view.LayoutInflater.inflate(LayoutInflater.java) at com.xtremelabs.robolectric.shadows.ShadowActivity.setContentView(ShadowActivity.java:101) at android.app.Activity.setContentView(Activity.java) at com.blah.MainActivity.onCreate(MainActivity.java:17) at com.blah.MainActivityTest.setUp(MainActivityTest.java:29) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41) at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:27)</p> <p>Caused by: java.lang.ClassCastException: com.blah.support.shadows.ShadowMultiDirectionSlidingDrawer cannot be cast to com.xtremelabs.robolectric.shadows.ShadowView at com.xtremelabs.robolectric.Robolectric.shadowOf(Robolectric.java:857) at com.xtremelabs.robolectric.shadows.ShadowViewGroup.addView(ShadowViewGroup.java:70) at android.view.ViewGroup.addView(ViewGroup.java) at com.xtremelabs.robolectric.shadows.ShadowViewGroup.addView(ShadowViewGroup.java:60) at android.view.ViewGroup.addView(ViewGroup.java) at com.xtremelabs.robolectric.res.ViewLoader$ViewNode.addToParent(ViewLoader.java:217) at com.xtremelabs.robolectric.res.ViewLoader$ViewNode.create(ViewLoader.java:180) at com.xtremelabs.robolectric.res.ViewLoader$ViewNode.inflate(ViewLoader.java:150) at com.xtremelabs.robolectric.res.ViewLoader$ViewNode.inflate(ViewLoader.java:153) at com.xtremelabs.robolectric.res.ViewLoader.inflateView(ViewLoader.java:102) ... 29 more</p> </blockquote> <p>I'm trying to work around this issue, because I don't care too much about testing this widget. Basically I want my tests not to crash and to verify that the view element is appearing on the screen.</p> <p>Someone suggested <a href="https://stackoverflow.com/questions/7250086/how-does-exactly-custom-shadow-objects-work-in-robolectric">a hack of placing the java file in a android package</a>, but I'm not sure if it applies in my case. As suggested by this answer, the custom widget lives in package "android" which is parallel to my com.blah structure.</p> <p>I created a shadow of the widget to get around the hostility issue (but currently I just comment out the exception throwing). Originally I wanted to bypass the work that was being done in the constructor since it relies on attributes that Robolectric isn't reporting correctly. The shadow constructor is getting called, but it continues through normal constructor execution. Is there a way to bypass additional construction?</p> <p><strong>ShadowClass</strong></p> <pre><code>@Implements (MultiDirectionSlidingDrawer.class) public class ShadowMultiDirectionSlidingDrawer { public void __constructor__( Context context, AttributeSet attrs ) { } public void __constructor__( Context context, AttributeSet attrs, int defStyle ) { } } </code></pre> <p><strong>Custom Test Runner</strong></p> <pre><code>public class CustomTestRunner extends RobolectricTestRunner { public CustomTestRunner( Class&lt;?&gt; testClass ) throws InitializationError { super( testClass ); addClassOrPackageToInstrument("android"); } @Override protected void bindShadowClasses() { super.bindShadowClasses(); Robolectric.bindShadowClass( ShadowMultiDirectionSlidingDrawer.class ); } } </code></pre> <p>Is this the right approach to work around the crashes until the testing framework supports this? Am I doing something wrong with my shadow or am I missing something else?</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload