NullPointerException при отражении во время запуска Robolectric – любые подсказки?

Я разрабатываю проект Android на Eclipse, и я пытаюсь переключиться с запуска тестов на эмулятор / устройство (которое очень медленно) на Robolectric .

Я заменил Android с помощью Robolectric, добавил JUnit на путь, сменил тестовый пример на регулярную TestCase и добавил предлагаемый @RunWith(RobolectricTestRunner.class) из руководства по быстрому @RunWith(RobolectricTestRunner.class) (внесение необходимых изменений для создания экземпляра моей деятельности вместо Полагаясь на тестирование активности Android, чтобы сделать это для меня).

Однако, когда я запускаю тест, я получаю:

 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) 

Кажется, что это связано с этим кодом ( с тега 0.9 , так как в теге 0.9.1 его нет) в RobolectricTestRunner.java :

 private static boolean isInstrumented() { return RobolectricTestRunner.class.getClassLoader().getClass().getName().contains(RobolectricClassLoader.class.getName()); } 

Но я не могу понять, как, поскольку это отражение должно работать из самого класса.

Кроме того, я мог бы поклясться, что он запускался один раз перед неудачей – я удалил кеш-роботек (как предлагается здесь ) и заменил JUnit Eclipse последним (4.8.2), но ничего не изменилось.

Любые намеки?

UPDATE: Я попытался создать новый тестовый проект Java (т. Е. Простой, не Android), как описано в кратком руководстве по началу работы. Тем не менее, теперь тестовый прогон жалуется на отсутствие AndroidManifest.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 

Я думаю, что тест должен загружать файлы из исходного проекта (minitruco-android), который отображается как на пути сборки тестового проекта, так и в конфигурации сборки Run / Debug на Eclipse (в элементе pathpath для тестового проекта). Во всяком случае, я скопировал файл из моего первоначального тестового проекта (только для тестирования), но потом он жалуется на R.java (и это действительно должно было быть импортировано из исходного проекта):

 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 

Единственная разница между моей настройкой и быстрым запуском заключается в том, что я храню тестовые ресурсы в тестовом проекте и регулярных источниках в обычном проекте (поскольку первые сборки я предполагаю, что тестовый проект видит обычные источники, которые, Конечно, это сильно зависит).

Я использую SoyLatte , но попробовал также Mac OS по умолчанию 1.6 JVM с теми же результатами.

Спасибо.

Обычно вам не нужно расширять TestCase, но я не думаю, что это должно было вызвать эту проблему. Не могли бы вы включить источник неудачного теста?

Что касается упрощенного проекта в вашем обновлении, убедитесь, что Eclipse настроен на то, чтобы установить текущий рабочий каталог в корень основного проекта, а не тестовый проект, поэтому он найдет AndroidManifest.xml и каталог res.

У нас были те же проблемы в прошлом. Для нас работает расширение RoboletricTestRunner и предоставление ему экземпляра RoboletricConfig, который знает местоположение нашего проекта. Таким образом, мне не нужно возиться с любыми конфигурациями запуска с помощью eclipse, это просто работает.

  package ...; import java.io.File; import org.junit.runners.model.InitializationError; import com.xtremelabs.robolectric.RobolectricConfig; import com.xtremelabs.robolectric.RobolectricTestRunner; public class TestRunner extends RobolectricTestRunner { public static final string MAIN_PROJECT_PATH = "../path_to_android_project"; public TestRunner(Class<?> testClass) throws InitializationError { super(testClass, new RobolectricConfig(new File(MAIN_PROJECT_PATH))); } } 

Не нужно создавать пользовательский RoboelectricTestRunner , просто немного поиграйте с «Run Configurations» на Eclipse . В конфигурации для запуска тестов перейдите на вкладку классов и убедитесь, что библиотеки, необходимые для вашего теста, например robolectric-2.2-jar-with-dependencies.jar и android.jar, и сам проект находятся в пользовательских записях и ТОЛЬКО Java SDK находится в записях Bootstrap .

Затем добавьте этот файл:

[project_path] /test/org.robolectric.Config.properties

  manifest=../AndroidManifest.xml