Исключение NullPointerException при отражении во время запуска Robolectric - любые подсказки?
Я разрабатываю проект Android на Eclipse, и я пытаюсь переключиться с запуска тестов на эмуляторе / устройстве (который очень медленно) к Robolectric.
Я заменил Android libs на Robolectric, добавил JUnit в путь, изменил тестовый случай на обычный TestCase
и добавить предложил @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 tag, так как тег 0.9.1 не имеет его) в RobolectricTestRunner.java
:
private static boolean isInstrumented() {
return RobolectricTestRunner.class.getClassLoader().getClass().getName().contains(RobolectricClassLoader.class.getName());
}
но я не могу понять как, так как это отражение должно работать от самого класса.
кроме того, я мог бы поклясться, что он работал один раз, прежде чем неоднократно терпел неудачу - я удалил кэш robolectric (как было предложено здесь) и заменил JUnit Eclipse на последний (4.8.2), но ничего не изменилось.
какие-то намеки?
обновление: я попытался создать новый, 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.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access0(ParentRunner.java:42)
at org.junit.runners.ParentRunner.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 (под записью classpath тестового проекта). Во всяком случае, я скопировал файл из своего исходного тестового проекта (просто для тестирования), но затем он жалуется на 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.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access0(ParentRunner.java:42)
at org.junit.runners.ParentRunner.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, с теми же результатами.
спасибо.
3 ответов
обычно вам не нужно будет расширять 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, просто немного поиграйте с вашими "конфигурациями запуска" на затмение. В конфигурации для запуска тестов перейдите на вкладку classpath и убедитесь, что библиотеки, необходимые для вашего теста, например robolectric-2.2-jar-with-dependencies.jar и android.банку и сам проект находятся в Записей Пользователей и только Java SDK находится в Загрузчик Записи.
затем добавить этот файл:
[project_path] / test / org.robolectric.Конфиг.свойства
manifest=../AndroidManifest.xml