title: Testing custom Views with Robolectric
body: <p>I'm trying to run unit tests with Robolectric 2.1.1 and I cannot get it to inflate custom layouts (e.g. ViewPagerIndicator classes). 
  Suppose this is my layout:</p>
  
  <pre><code>&lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
                android:orientation="vertical"
                android:layout_width="match_parent"
                android:layout_height="match_parent"&gt;
  
      &lt;TextView
              android:layout_width="fill_parent"
              android:layout_height="wrap_content"
              android:text="test"
              android:id="@+id/test_test"/&gt;
  
      &lt;com.viewpagerindicator.CirclePageIndicator
              android:layout_width="fill_parent"
              android:layout_height="wrap_content"/&gt;
  
  &lt;/LinearLayout&gt;
  </code></pre>
  
  <p>Consider this my test class:</p>
  
  <pre><code>@RunWith(RobolectricTestRunner.class)
  public class TestRoboActivityTest {
      private TestRoboActivity mActivity;
  
      @Before
      public void setUp() throws Exception {
          mActivity = Robolectric.buildActivity(TestRoboActivity.class).create().get();
      }
  
      @After
      public void tearDown() throws Exception {
          mActivity = null;
      }
  
      @Test
      public void testSanity() throws Exception {
          Assert.assertNotNull(mActivity);
      }
  }
  </code></pre>
  
  <p>Executing 'mvn clean test' results in </p>
  
  <pre>
  Tests in error:
  testSanity(TestRoboActivityTest): XML file .\res\layout\test.xml line #-1 (sorry, not yet implemented): Error inflating class com.viewpagerindicator.CirclePageIndicator
  </pre>
  
  <p>Cool, so it seems like custom views aren't supported yet. Checking the sample Robolectric project on their <a href="https://github.com/robolectric/RobolectricSample/blob/master/src/test/java/com/pivotallabs/views/LoadingTextViewTest.java" rel="noreferrer">website</a>, 
  one solution could be to inflate the layout from LayoutInflater:</p>
  
  <pre><code>@RunWith(RobolectricTestRunner.class)
  public class TestRoboActivityTest {
      private View mTestRoboActivityView;
  
      @Before
      public void setUp() throws Exception {
          mTestRoboActivityView = LayoutInflater.from(new Activity()).inflate(R.layout.test, null);
      }
  
      @After
      public void tearDown() throws Exception {
          mTestRoboActivityView = null;
      }
  
      @Test
      public void testSanity() throws Exception {
          Assert.assertNotNull(mTestRoboActivityView);
      }
  }
  </code></pre>
  
  <p>which results in: </p>
  
  <pre>
  Tests in error: 
  testSanity(TestRoboActivityTest): XML file .\res\layout\test.xml line #-1 (sorry, not yet implemented): Error inflating class com.viewpagerindicator.CirclePageIndicator
  </pre>
  
  <p>My last resort was trying to use shadow classes: </p>
  
  <pre><code>@Implements(CirclePageIndicator.class)
  public class CirclePageIndicatorShadow implements PageIndicator {
  
      @Override
      @Implementation
      public void setViewPager(ViewPager view) {
          // Stub
      }
  
      // etc.
  }
  </code></pre>
  
  <p>and using <code>@Config(shadows = {CirclePageIndicatorShadow.class})</code>. This again resulted in </p>
  
  <pre>
  Tests in error: 
  testSanity(TestRoboActivityTest): XML file .\res\layout\test.xml line #-1 (sorry, not yet implemented): Error inflating class com.viewpagerindicator.CirclePageIndicator
  </pre>
  
  <hr>
  
  <p><strong>Edit (December 2014)</strong></p>
  
  <p>Please note that the following stracktrace was added later by David Rabinowitz. While related, it is not the issue I was facing at the time.</p>
  
  <hr>
  
  <p>Here is the stack trace:</p>
  
  <pre><code>android.view.InflateException: XML file .\res\layout\activity_home.xml line #-1 (sorry, not yet implemented): Error inflating class com.test.custom.RobotoTextView
      at android.view.LayoutInflater.createView(LayoutInflater.java:613)
      at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:687)
      at android.view.LayoutInflater.rInflate(LayoutInflater.java:746)
      at android.view.LayoutInflater.inflate(LayoutInflater.java:489)
      at android.view.LayoutInflater.inflate(LayoutInflater.java:396)
      at android.view.LayoutInflater.inflate(LayoutInflater.java:352)
      at org.robolectric.tester.android.view.RoboWindow.setContentView(RoboWindow.java:82)
      at org.robolectric.shadows.ShadowActivity.setContentView(ShadowActivity.java:273)
      at android.app.Activity.setContentView(Activity.java)
      at com.example.testrobocustomfont.MainActivity.onCreate(MainActivity.java:12)
      at com.example.testrobocustomfont.MainActivityTest.setUp(MainActivityTest.java:28)
      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)
      at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
      at org.robolectric.RobolectricTestRunner$2.evaluate(RobolectricTestRunner.java:241)
      at org.junit.runners.BlockJUnit4ClassRunner.runNotIgnored(BlockJUnit4ClassRunner.java:79)
      at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:71)
      at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
      at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
      at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
      at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
      at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
      at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
      at org.robolectric.RobolectricTestRunner$1.evaluate(RobolectricTestRunner.java:177)
      at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
      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)
  Caused by: java.lang.reflect.InvocationTargetException
      at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
      at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
      at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
      at java.lang.reflect.Constructor.newInstance(Constructor.java:525)
      at android.view.LayoutInflater.$$robo$$LayoutInflater_1d1f_createView(LayoutInflater.java:587)
      at android.view.LayoutInflater.createView(LayoutInflater.java)
      at android.view.LayoutInflater.$$robo$$LayoutInflater_1d1f_createViewFromTag(LayoutInflater.java:687)
      at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java)
      at android.view.LayoutInflater.$$robo$$LayoutInflater_1d1f_rInflate(LayoutInflater.java:746)
      at android.view.LayoutInflater.rInflate(LayoutInflater.java)
      at android.view.LayoutInflater.$$robo$$LayoutInflater_1d1f_inflate(LayoutInflater.java:489)
      at android.view.LayoutInflater.inflate(LayoutInflater.java)
      at android.view.LayoutInflater.$$robo$$LayoutInflater_1d1f_inflate(LayoutInflater.java:396)
      at android.view.LayoutInflater.inflate(LayoutInflater.java)
      at android.view.LayoutInflater.$$robo$$LayoutInflater_1d1f_inflate(LayoutInflater.java:352)
      at android.view.LayoutInflater.inflate(LayoutInflater.java)
      at org.robolectric.tester.android.view.RoboWindow.setContentView(RoboWindow.java:82)
      at org.robolectric.shadows.ShadowActivity.setContentView(ShadowActivity.java:273)
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      at java.lang.reflect.Method.invoke(Method.java:601)
      at org.robolectric.bytecode.ShadowWrangler$ShadowMethodPlan.run(ShadowWrangler.java:455)
      at android.app.Activity.setContentView(Activity.java)
      at com.example.testrobocustomfont.MainActivity.onCreate(MainActivity.java:12)
      at com.example.testrobocustomfont.MainActivityTest.setUp(MainActivityTest.java:28)
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      at java.lang.reflect.Method.invoke(Method.java:601)
      ... 22 more
  Caused by: java.lang.RuntimeException: error converting RobotoMedium.ttf using EnumConverter
      at org.robolectric.shadows.Converter.convertAndFill(Converter.java:150)
      at org.robolectric.shadows.Converter.convertAndFill(Converter.java:50)
      at org.robolectric.shadows.ShadowResources.createTypedArray(ShadowResources.java:228)
      at org.robolectric.shadows.ShadowResources.attrsToTypedArray(ShadowResources.java:203)
      at org.robolectric.shadows.ShadowResources.access$000(ShadowResources.java:51)
      at org.robolectric.shadows.ShadowResources$ShadowTheme.obtainStyledAttributes(ShadowResources.java:460)
      at android.content.res.Resources$Theme.obtainStyledAttributes(Resources.java)
      at android.widget.TextView.__constructor__(TextView.java:561)
      at android.widget.TextView.&lt;init&gt;(TextView.java:447)
      at android.widget.TextView.&lt;init&gt;(TextView.java:442)
      at com.test.custom.RobotoTextView.&lt;init&gt;(RobotoTextView.java:16)
      at android.view.LayoutInflater.createView(LayoutInflater.java:587)
      at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:687)
      at android.view.LayoutInflater.rInflate(LayoutInflater.java:746)
      at android.view.LayoutInflater.inflate(LayoutInflater.java:489)
      at android.view.LayoutInflater.inflate(LayoutInflater.java:396)
      at android.view.LayoutInflater.inflate(LayoutInflater.java:352)
      at org.robolectric.tester.android.view.RoboWindow.setContentView(RoboWindow.java:82)
      at org.robolectric.shadows.ShadowActivity.setContentView(ShadowActivity.java:273)
      at android.app.Activity.setContentView(Activity.java)
      at com.example.testrobocustomfont.MainActivity.onCreate(MainActivity.java:12)
      at com.example.testrobocustomfont.MainActivityTest.setUp(MainActivityTest.java:28)
      ... 22 more
  Caused by: java.lang.RuntimeException: no value found for RobotoMedium.ttf
      at org.robolectric.shadows.Converter$EnumOrFlagConverter.findValueFor(Converter.java:375)
      at org.robolectric.shadows.Converter$EnumConverter.fillTypedValue(Converter.java:343)
      at org.robolectric.shadows.Converter$EnumConverter.fillTypedValue(Converter.java:336)
      at org.robolectric.shadows.Converter.convertAndFill(Converter.java:148)
      at org.robolectric.shadows.Converter.convertAndFill(Converter.java:50)
      at org.robolectric.shadows.ShadowResources.createTypedArray(ShadowResources.java:228)
      at org.robolectric.shadows.ShadowResources.attrsToTypedArray(ShadowResources.java:203)
      at org.robolectric.shadows.ShadowResources.access$000(ShadowResources.java:51)
      at org.robolectric.shadows.ShadowResources$ShadowTheme.obtainStyledAttributes(ShadowResources.java:460)
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      at java.lang.reflect.Method.invoke(Method.java:601)
      at org.robolectric.bytecode.ShadowWrangler$ShadowMethodPlan.run(ShadowWrangler.java:455)
      at android.content.res.Resources$Theme.obtainStyledAttributes(Resources.java)
      at android.widget.TextView.$$robo$$TextView_347d___constructor__(TextView.java:561)
      at android.widget.TextView.&lt;init&gt;(TextView.java:447)
      at android.widget.TextView.&lt;init&gt;(TextView.java:442)
      at com.test.custom.RobotoTextView.&lt;init&gt;(RobotoTextView.java:16)
      at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
      at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
      at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
      at java.lang.reflect.Constructor.newInstance(Constructor.java:525)
      at android.view.LayoutInflater.$$robo$$LayoutInflater_1d1f_createView(LayoutInflater.java:587)
      at android.view.LayoutInflater.createView(LayoutInflater.java)
      at android.view.LayoutInflater.$$robo$$LayoutInflater_1d1f_createViewFromTag(LayoutInflater.java:687)
      at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java)
      at android.view.LayoutInflater.$$robo$$LayoutInflater_1d1f_rInflate(LayoutInflater.java:746)
      at android.view.LayoutInflater.rInflate(LayoutInflater.java)
      at android.view.LayoutInflater.$$robo$$LayoutInflater_1d1f_inflate(LayoutInflater.java:489)
      at android.view.LayoutInflater.inflate(LayoutInflater.java)
      at android.view.LayoutInflater.$$robo$$LayoutInflater_1d1f_inflate(LayoutInflater.java:396)
      at android.view.LayoutInflater.inflate(LayoutInflater.java)
      at android.view.LayoutInflater.$$robo$$LayoutInflater_1d1f_inflate(LayoutInflater.java:352)
      at android.view.LayoutInflater.inflate(LayoutInflater.java)
      at org.robolectric.tester.android.view.RoboWindow.setContentView(RoboWindow.java:82)
      at org.robolectric.shadows.ShadowActivity.setContentView(ShadowActivity.java:273)
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      at java.lang.reflect.Method.invoke(Method.java:601)
      at org.robolectric.bytecode.ShadowWrangler$ShadowMethodPlan.run(ShadowWrangler.java:455)
      at android.app.Activity.setContentView(Activity.java)
      at com.example.testrobocustomfont.MainActivity.onCreate(MainActivity.java:12)
      at com.example.testrobocustomfont.MainActivityTest.setUp(MainActivityTest.java:28)
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      at java.lang.reflect.Method.invoke(Method.java:601)
      ... 22 more
  </code></pre>
  
  <p>Could you guys please point me in the right direction? I'm out of ideas.
  Thanks.</p>