Robolectric не может найти ресурс или файл манифеста

Я создал новый TestProject и добавил следующую строку в свой testMethod:

Robolectric.getShadowApplication().getString(R.string.mystring);

Мой тест не удался с

android.content.res.Resources$NotFoundException: unknown resource 2131558482

На консоли отображаются следующие предупреждения:

WARNING: No manifest file found at .\..\..\MyProject\AndroidManifest.xml.Falling back to the Android OS resources only.
To remove this warning, annotate your test class with @Config(manifest=Config.NONE).
WARNING: no system properties value for ro.build.date.utc

Требуется ли AndroidManifest.xml для получения строковых ресурсов? Я попытался добавить Manifest с помощью org.robolectric.Config.properties и @Config, но предупреждение все еще появляется, и я не могу получить строковый ресурс. Я убедился, что относительный путь к манифесту правильный. Я также попытался изменить конфигурацию запуска JUnit, но это не помогло.

Ответы

Ответ 1

Решение проблемы, описанной здесь: http://blog.futurice.com/android_unit_testing_in_ides_and_ci_environments

Пропавший манифест

Вы должны были заметить, что Robolectric жалуется на то, что не смог найти ваш манифест Android. Хорошо исправить это, написав пользовательский тестовый бегун. Добавьте следующее: app/src/test/java/com/example/app/test/RobolectricGradleTestRunner.java:

package com.example.app.test;

import org.junit.runners.model.InitializationError;
import org.robolectric.manifest.AndroidManifest;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
import org.robolectric.res.Fs;

public class RobolectricGradleTestRunner extends RobolectricTestRunner {
  public RobolectricGradleTestRunner(Class<?> testClass) throws InitializationError {
    super(testClass);
  }

  @Override
  protected AndroidManifest getAppManifest(Config config) {
    String myAppPath = RobolectricGradleTestRunner.class.getProtectionDomain()
                                                        .getCodeSource()
                                                        .getLocation()
                                                        .getPath();
    String manifestPath = myAppPath + "../../../src/main/AndroidManifest.xml";
    String resPath = myAppPath + "../../../src/main/res";
    String assetPath = myAppPath + "../../../src/main/assets";
    return createAppManifest(Fs.fileFromPath(manifestPath), Fs.fileFromPath(resPath), Fs.fileFromPath(assetPath));
  }
}

Не забудьте изменить аннотацию RunWith в тестовом классе.

Ответ 2

Я столкнулся с такими же ошибками. Мы использовали несколько вариантов и типов сборки. Итак, есть шаги, чтобы заставить его работать:

1) Тесты студии Android запускают конфигурацию

Вы также должны установить рабочий каталог в $MODULE_DIR $в Windows. http://robolectric.org/getting-started/ должен сказать это.

2) Unit test следует аннотировать следующим образом:

@RunWith(RobolectricTestRunner.class) 
@Config(constants = BuildConfig.class, sdk = 21, manifest = "src/main/AndroidManifest.xml", packageName = "com.example.yourproject") 
public class SomeFragmentTest {

Здесь у нас есть простая ссылка на файл manifest и packageName

Ответ 3

Вам понадобится AndroidManifest.xml, и в настоящее время Robolectric зависит от того, что он находится в корне проекта, как следует из пути.

Ответ 4

Я заметил, что я использовал объявление вроде этого в верхней части моего тестового класса

@RunWith(RobolectricTestRunner.class)
@Config( constants = BuildConfig.class, manifest="app/src/main/AndroidManifest.xml", sdk = 21 )

И я переключился на это, чтобы работать.

@RunWith(RobolectricTestRunner.class)
@Config( constants = BuildConfig.class, manifest="src/main/AndroidManifest.xml", sdk = 21 )

Ответ 5

Я только что решил ту же проблему с Robolectric (ver: robolectric-2.4-jar-with-dependencies.jar) и возвратил неизвестные ресурсы при загрузке resouce из разных значений - * папок, например:

<resources>
    <string name="screen_type">10-inch-tablet</string>
</resources>

В моем случае я хотел распознать разные устройства. По этой причине я создал screen.xml в следующих папках:

values/screen.xml - mobile
values-sw600dp/screen.xml - 7-inch tablet
values-sw720dp/screen.xml - 10-inch tablet

Мое рабочее пространство выглядит следующим образом:

workspace
   \-ExProj
       \-exProj
            \-src
                \-exProj
                    \-AndroidManifest.xml
   \-ExProjTest

Мой unit test с Robolectric:

@RunWith(RobolectricTestRunner.class)
@Config(manifest = "./../ExProj/exProj/src/exProj/AndroidManifest.xml")
public class UtilityTest {

  @Test
   @Config(qualifiers = "sw720dp")
    public void testIfDeviceIsTablet() throws Exception {
     System.out.println(Robolectric.application.getString(R.string.screen_type));
    }
}

Выше тестового кода выдается на консоль: 10-дюймовый планшет...

Ответ 6

Я перегрузил getConfigProperties() путем подкласса RobolectricTestRunner. Следуйте по этой ссылке: fooobar.com/questions/73708/...

Ответ 7

Начиная с версии 4.0, использование @Config высоко ценится, однако обновленное руководство по началу работы решает мою проблему: http://robolectric.org/getting-started/

Можно запустить только одну модификацию build.gradle и загрузить файл Manifest.

android {
  testOptions {
    unitTests {
      includeAndroidResources = true
    }
  }
}

Связанная проблема на github (также была закрыта): https://github.com/robolectric/robolectric/issues/3328