Ресурсы $NotFoundException при использовании Robolectric с Gradle

Я следил за этот учебник о настройке Robolectric для тестирования моего Android-проекта Gradle.

Я продолжаю эту ошибку:

android.content.res.Resources$NotFoundException: no such label com.mypackage.dev:string/app_name

Загрузив образец проекта из учебника, я установил, что проблема заключается в моей productFlavors (dev, staging, production). Добавление вкусов к рабочему образцу проекта вызывает ту же проблему. Вы можете увидеть схему моего build.gradle в этом ответе.

Я видел различные ответы (например, здесь), которые предполагают, что мне нужно указать sourceSets для каждого аромата. Я пробовал много комбинаций, но не могу понять это правильно. Может ли кто-нибудь помочь?

Другое, что меня смущает, это то, что все образцы Robolectric, которые я видел, по-видимому, задают исходные наборы и зависимости для "инструментального теста", хотя тесты Robolectric всегда находятся только в папке "test". В моем случае у меня уже есть тесты Robotium в папке instrumentTest, и я не понимаю, почему мне нужно будет добавлять зависимости Robolectric для кода Robotium.

Ответ 1

Я наткнулся на ту же проблему (ресурсы не найдены) и нашел решение на робоэлектрическом источнике. Существует Setter для PackageName, поэтому в моем пользовательском тестовом ядре я устанавливаю имя пакета перед возвратом манифеста. Что-то вроде:

@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 manifest = new AndroidManifest(Fs.fileFromPath(manifestProperty), Fs.fileFromPath(resProperty),
                Fs.fileFromPath(assetsProperty));
        manifest.setPackageName("com.mypackagename");
        return manifest;
    }
    return super.getAppManifest(config);
}

Надеюсь, это поможет.

Ответ 2

Robolectric исправил эту проблему в версии 3.0. Поэтому просто используйте последнюю версию Robolectric с определенным параметром const в аннотации @Config.

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

@RunWith(RobolectricTestRunner.class)

Кроме того, один важный элемент - для правильной работы Robolectric ваш applicationId в gradle.build должен быть равен package в AndroidManifest. Использование applicationIdSuffix не влияет на Robolectric.

Ответ 3

Вы можете исправить это, указав "packageName" в своем @Config, чтобы он стал:

@Config(
        sdk = 21, 
        manifest="src/main/AndroidManifest.xml",
        constants = BuildConfig.class,
        packageName = "com.mypackage" //this is whatever value is your AndroidManifest.xml at <manifest ... package="com.mypackage".../>
)