Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Robolectric 2.4 NoSuchMethodError cannot be cast to RuntimeException when creating activity

I am starting to use Robolectric in Android Studio. At first I wanted to create a simple test using hamcrest, which is shown below:

@RunWith(CustomTestRunner.class)
@Config(emulateSdk = 18)
public class MainActivityTest {

    private MainActivity mainActivity;


    @Test
    public void testMainActivity() {
        mainActivity = buildActivity(MainActivity.class).create().get();
        assertThat(mainActivity, notNullValue());
    }

}

When executing the test throws the following exception:

java.lang.ClassCastException: java.lang.NoSuchMethodError cannot be cast to java.lang.RuntimeException
    at org.robolectric.internal.ReflectionHelpers.callInstanceMethodReflectively(ReflectionHelpers.java:68)
    at org.robolectric.util.ActivityController$1.run(ActivityController.java:115)
    at org.robolectric.shadows.ShadowLooper.runPaused(ShadowLooper.java:268)
    at org.robolectric.util.ActivityController.create(ActivityController.java:111)
    at org.robolectric.util.ActivityController.create(ActivityController.java:122)
    at com.enprodo.wakemethere.googleservices.geofence.GeofenceTest.testReceiver(GeofenceTest.java:31)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.robolectric.RobolectricTestRunner$2.evaluate(RobolectricTestRunner.java:236)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.robolectric.RobolectricTestRunner$1.evaluate(RobolectricTestRunner.java:158)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:74)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:211)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:67)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)

The CustomTestRunner class looks like this:

public class CustomTestRunner extends RobolectricTestRunner {

    public CustomTestRunner(Class<?> testClass) throws InitializationError {
        super(testClass);
    }

    @Override
    protected AndroidManifest getAppManifest(Config config) {
        String manifestProperty = System.getProperty("android.manifest");
        if (config.manifest().equals(Config.DEFAULT) && manifestProperty != null) {
            String resProperty = System.getProperty("android.resources");
            String assetsProperty = System.getProperty("android.assets");
            AndroidManifest androidManifest = new AndroidManifest(
                    Fs.fileFromPath(manifestProperty),
                    Fs.fileFromPath(resProperty),
                    Fs.fileFromPath(assetsProperty));
            androidManifest.setPackageName("com.package");
            return androidManifest;
        }
        return super.getAppManifest(config);
    }
}

I can add that MainActivity extends android.support.v7.app.ActionBarActivity but I have no idea if that affects the behaviour.

After some digging in the Robolectric source it appears the error appears when this is executed:

ReflectionHelpers.callInstanceMethodReflectively(component, "performCreate", new ReflectionHelpers.ClassParameter(Bundle.class, bundle));

The code of callInstanceMethodReflectively looks like this:

  public static <R> R callInstanceMethodReflectively(final Object instance, final String methodName, ClassParameter... classParameters) {
    try {
      final Class[] classes = ClassParameter.getClasses(classParameters);
      final Object[] values = ClassParameter.getValues(classParameters);

      return traverseClassHierarchy(instance.getClass(), NoSuchMethodException.class, new InsideTraversal<R>() {
        @Override
        public R run(Class traversalClass) throws Exception {
          Method declaredMethod = traversalClass.getDeclaredMethod(methodName, classes);
          declaredMethod.setAccessible(true);
          return (R) declaredMethod.invoke(instance, values);
        }
      });
    } catch (InvocationTargetException e) {
      throw (RuntimeException) e.getTargetException();
    } catch (Exception e) {
      throw new RuntimeException(e);
    }
  }

I am not a reflection expert, but it seems that somehow the performCreate method cannot be found. Has anyone encountered similar issue? Does anyone have any idea what could be the problem?

like image 508
yac00b Avatar asked Nov 01 '22 11:11

yac00b


1 Answers

After some more digging it appears that with Robolectric 2.4 some issues with ActionBarActivity appear. According to this issue full support for appcompat-v7 will be provided in Robolectric 3.0. Indeed trying Robolectric 3.0-SNAPSHOT solved the issue.

like image 97
yac00b Avatar answered Nov 15 '22 04:11

yac00b