Java – NullPointerException reflected when robolectric starts – any hint?
I'm developing an Android project on eclipse and I'm trying to switch from running tests on the simulator / device (very slow) to robolectric
I replaced the Android library with robolectric, added JUnit to the path, changed the test case back to the regular testcase, and added the suggested @ runwith (robolectrictetrunner. Class) from the Quick Start Guide (make necessary changes to instantiate my activity instead of relying on the Android activity test to do this for me)
However, when I run the test, I get:
java.lang.NullPointerException at com.xtremelabs.robolectric.RobolectricTestRunner.isInstrumented(RobolectricTestRunner.java:123) at com.xtremelabs.robolectric.RobolectricTestRunner.<init>(RobolectricTestRunner.java:72) at com.xtremelabs.robolectric.RobolectricTestRunner.<init>(RobolectricTestRunner.java:57) 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:532) at org.junit.internal.builders.AnnotatedBuilder.buildrunner(AnnotatedBuilder.java:31) at org.junit.internal.builders.AnnotatedBuilder.runnerForClass(AnnotatedBuilder.java:24) at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:57) at org.junit.internal.builders.AllDefaultPossibilitiesBuilder.runnerForClass(AllDefaultPossibilitiesBuilder.java:29) at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:57) at org.junit.internal.requests.ClassRequest.getRunner(ClassRequest.java:24) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.<init>(JUnit4TestReference.java:29) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestClassReference.<init>(JUnit4TestClassReference.java:25) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.createTest(JUnit4TestLoader.java:40) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.loadTests(JUnit4TestLoader.java:30) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:452) 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)
This seems to be related to robolectrictestrunner This code in Java (from 0.9 tag, because the 0.9.1 tag does not have it) is related to:
private static boolean isInstrumented() { return RobolectricTestRunner.class.getClassLoader().getClass().getName().contains(RobolectricClassLoader.class.getName()); }
But I can't understand, because this reflection should come from the class itself
In addition, I can swear that it ran once before repeated failures - I have deleted the robolectric cache (as suggested here) and replaced eclipse's JUnit with the latest version (4.8.2), but nothing has changed
Any tips?
Update: I tried to create a new Java (i.e. simple non Android) test project, as described in the quick start guide However, now the test run complains that there is no android manifest xml:
java.lang.RuntimeException: java.io.FileNotFoundException: /Users/chester/Documents/workspace/minitruco-android/minitruco-android-robolectric-test/AndroidManifest.xml (No such file or directory) at com.xtremelabs.robolectric.RobolectricTestRunner.createResourceLoader(RobolectricTestRunner.java:245) at com.xtremelabs.robolectric.RobolectricTestRunner.setupApplicationState(RobolectricTestRunner.java:215) at com.xtremelabs.robolectric.RobolectricTestRunner.internalBeforeTest(RobolectricTestRunner.java:163) at com.xtremelabs.robolectric.RobolectricTestRunner.methodBlock(RobolectricTestRunner.java:143) 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.junit.runners.ParentRunner.run(ParentRunner.java:236) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:46) 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.io.FileNotFoundException: /Users/chester/Documents/workspace/minitruco-android/minitruco-android-robolectric-test/AndroidManifest.xml (No such file or directory) at java.io.FileInputStream.open(Native Method) at java.io.FileInputStream.<init>(FileInputStream.java:137) at java.io.FileInputStream.<init>(FileInputStream.java:96) at sun.net.www.protocol.file.FileURLConnection.connect(FileURLConnection.java:87) at sun.net.www.protocol.file.FileURLConnection.getInputStream(FileURLConnection.java:178) at com.sun.org.apache.xerces.internal.impl.XMLEntityManager.setupCurrentEntity(UnkNown Source) at com.sun.org.apache.xerces.internal.impl.XMLVersionDetector.determineDocVersion(UnkNown Source) at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(UnkNown Source) at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(UnkNown Source) at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(UnkNown Source) at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(UnkNown Source) at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(UnkNown Source) at javax.xml.parsers.DocumentBuilder.parse(UnkNown Source) at com.xtremelabs.robolectric.RobolectricTestRunner.findResourcePackageName(RobolectricTestRunner.java:255) at com.xtremelabs.robolectric.RobolectricTestRunner.createResourceLoader(RobolectricTestRunner.java:236) ... 18 more
I think the test should load files from the original project (minitruco Android), which are displayed in the build path of the test project and the run / debug build configuration on eclipse (under the classpath entry of the test project) Anyway, I've copied the file from my original test project (just for testing), but later it complained about r.java (and should really be imported from the original project):
java.lang.RuntimeException: java.lang.ClassNotFoundException: caught an exception while obtaining a class file for me.chester.minitruco.test.R at com.xtremelabs.robolectric.RobolectricTestRunner.createResourceLoader(RobolectricTestRunner.java:245) at com.xtremelabs.robolectric.RobolectricTestRunner.setupApplicationState(RobolectricTestRunner.java:215) at com.xtremelabs.robolectric.RobolectricTestRunner.internalBeforeTest(RobolectricTestRunner.java:163) at com.xtremelabs.robolectric.RobolectricTestRunner.methodBlock(RobolectricTestRunner.java:143) 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.junit.runners.ParentRunner.run(ParentRunner.java:236) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:46) 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.ClassNotFoundException: caught an exception while obtaining a class file for me.chester.minitruco.test.R at javassist.Loader.findClass(Loader.java:359) at com.xtremelabs.robolectric.RobolectricClassLoader.findClass(RobolectricClassLoader.java:60) at javassist.Loader.loadClass(Loader.java:311) at java.lang.ClassLoader.loadClass(ClassLoader.java:268) at com.xtremelabs.robolectric.RobolectricClassLoader.loadClass(RobolectricClassLoader.java:37) at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:336) at java.lang.Class.forName0(Native Method) at java.lang.Class.forName(Class.java:186) at com.xtremelabs.robolectric.RobolectricTestRunner.createResourceLoader(RobolectricTestRunner.java:237) ... 18 more Caused by: javassist.NotFoundException: me.chester.minitruco.test.R at javassist.ClassPool.get(ClassPool.java:436) at com.xtremelabs.robolectric.AndroidTranslator.onLoad(AndroidTranslator.java:68) at javassist.Loader.findClass(Loader.java:340) ... 26 more
The only difference between my setup and quick launch is that I keep the test source on the regular source of the test project and the regular project (since the first build, I assume that the test project sees the regular source – which, of course, depends largely on)
I'm using soylatte, but I also tried the default 1.6 JVM for Mac OS, and the results are the same
thank you.
Solution
Usually you don't need to extend testcase, but I don't think it should lead to this problem Can you include the source of the failed test?
For the simplified project in the update, make sure eclipse is configured to set the current working directory as the root directory of the main project, not the test project, so it will find androidmanifest XML and res directories