Как получить доступ к файлам из папки с данными при выполнении тестов?

Как получить доступ к файлам из папки с данными при выполнении единичных тестов? Мой проект построен с использованием Gradle, я использую Robolectric для запуска тестов. Кажется, что град признает assets :

Введите описание изображения здесь

Вот как я изо всех сил пытаюсь прочитать файл:

 public String readFileFromAssets(String fileName) throws IOException { InputStream stream = getClass().getClassLoader().getResourceAsStream("assets/" + fileName); Preconditions.checkNotNull(stream, "Stream is null"); BufferedReader reader = new BufferedReader(new InputStreamReader(stream, "UTF-8")); return IOUtils.toString(reader); } 

Но stream всегда равен null . Я пробовал это много разных способов, то есть определенный путь к файлу с использованием разных подходов.

Заранее большое спасибо.

В основном вы должны использовать Context для чтения активов. Вы не можете загружать активы с помощью ClassLoader поскольку он не находится в пути к классам. Я не уверен, как вы запускаете тесты Robolectric. Вот как я могу добиться как в студии Android, так и в команде gralde.

Я добавил отдельный модуль тестирования приложений для запуска тестов Robolectric в проекте приложения. При правильной конфигурации сборки и пользовательских RobolectricTestRunner , следующий тест будет проходить.

 @Config @RunWith(MyRobolectricTestRunner.class) public class ReadAssetsTest { @Test public void test_ToReadAssetsFileInAndroidTestContext() throws IOException { ShadowApplication application = Robolectric.getShadowApplication(); Assert.assertNotNull(application); InputStream input = application.getAssets().open("b.xml"); Assert.assertNotNull(input); } } 

приложение-блок-тест / build.gradle

 buildscript { repositories { jcenter() } dependencies { classpath 'com.android.tools.build:gradle:0.14.1' } } apply plugin: 'java' evaluationDependsOn(':app') sourceCompatibility = JavaVersion.VERSION_1_7 targetCompatibility = JavaVersion.VERSION_1_7 repositories { maven { url "$System.env.ANDROID_HOME/extras/android/m2repository" } // Fix 'com.android.support:*' package not found issue mavenLocal() mavenCentral() jcenter() } dependencies { testCompile 'junit:junit:4.8.2' testCompile('org.robolectric:robolectric:2.4') { exclude module: 'classworlds' exclude module: 'commons-logging' exclude module: 'httpclient' exclude module: 'maven-artifact' exclude module: 'maven-artifact-manager' exclude module: 'maven-error-diagnostics' exclude module: 'maven-model' exclude module: 'maven-project' exclude module: 'maven-settings' exclude module: 'plexus-container-default' exclude module: 'plexus-interpolation' exclude module: 'plexus-utils' exclude module: 'wagon-file' exclude module: 'wagon-http-lightweight' exclude module: 'wagon-provider-api' exclude group: 'com.android.support', module: 'support-v4' } testCompile('com.squareup:fest-android:1.0.+') { exclude group: 'com.android.support', module: 'support-v4' } testCompile 'org.mockito:mockito-core:1.10.10' def appModule = project(':app') testCompile(appModule) { exclude group: 'com.google.android' exclude module: 'dexmaker-mockito' } testCompile appModule.android.applicationVariants.toList().first().javaCompile.classpath testCompile appModule.android.applicationVariants.toList().first().javaCompile.outputs.files testCompile 'com.google.android:android:4.1.1.4' /* FIXME : prevent Stub! error testCompile files(appModule.plugins.findPlugin("com.android.application").getBootClasspath()) */ compile project(':app') } 

Добавьте настраиваемый RobolectricTestRunner для настройки путей к файлам. Посмотрите на путь активов.

 public class MyRobolectricTestRunner extends RobolectricTestRunner { private static final String APP_MODULE_NAME = "app"; /** * Creates a runner to run {@code testClass}. Looks in your working directory for your AndroidManifest.xml file * and res directory by default. Use the {@link org.robolectric.annotation.Config} annotation to configure. * * @param testClass the test class to be run * @throws org.junit.runners.model.InitializationError if junit says so */ public MyRobolectricTestRunner(Class<?> testClass) throws InitializationError { super(testClass); System.out.println("testclass="+testClass); } @Override protected AndroidManifest getAppManifest(Config config) { String userDir = System.getProperty("user.dir", "./"); File current = new File(userDir); String prefix; if (new File(current, APP_MODULE_NAME).exists()) { System.out.println("Probably running on AndroidStudio"); prefix = "./" + APP_MODULE_NAME; } else if (new File(current.getParentFile(), APP_MODULE_NAME).exists()) { System.out.println("Probably running on Console"); prefix = "../" + APP_MODULE_NAME; } else { throw new IllegalStateException("Could not find app module, app module should be \"app\" directory in the project."); } System.setProperty("android.manifest", prefix + "/src/main/AndroidManifest.xml"); System.setProperty("android.resources", prefix + "/src/main/res"); System.setProperty("android.assets", prefix + "/src/androidTest/assets"); return super.getAppManifest(config); } } 

Я пошел за этим блогом, чтобы сделать это.

Полный код примера здесь .

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

Я помещал тестовые файлы в папку src/test/resources вместо папки с папками.

Затем я получаю эти файлы как поток следующим образом

 private InputStream openFile(String filename) throws IOException { return getClass().getClassLoader().getResourceAsStream(filename); } 

filename – относительный путь к файлу внутри папки resources .

Вот и все. Я нашел решение в Robolectric github

Обновление для Roboelectric 3.1

  @Test public void shouldGetJSONFromAsset() throws Exception{ Assert.assertNotNull(RuntimeEnvironment.application); //Getting the application context InputStream input = RuntimeEnvironment.application.getAssets().open("fileName.xml");// the file name in asset folder Assert.assertNotNull(input); } 

Смотрите также

  1. Руководство по обновлению от 2,4 до 3,0
  2. 3.0 до 3.1 Руководство по обновлению

Путеводитель

Вы пытались поместить папку с ресурсами в main вместо androidTest?

Кроме того, вы используете https://github.com/robolectric/robolectric-gradle-plugin для запуска тестов?

С последним тестом на Android Instrumentation Test вы можете просто использовать это:

 InstrumentationRegistry.getContext().getAssets().open(filePath); 

Если все правильно, вам понадобится что-то подобное, чтобы прочитать его:

 public String readFileFromAssets(String fileName, Context context) throws IOException { InputStreamReader stream = new InputStreamReader(context.getAssets().open(fileName)); Preconditions.checkNotNull(stream, "Stream is null"); BufferedReader reader = new BufferedReader(new InputStreamReader(stream, "UTF-8")); return IOUtils.toString(reader); } 

Вам нужно передать контекст, чтобы он работал.

Еще одна вещь, чтобы проверить, правильно ли вы настроили активы в Gradle? Вот лишь пример:

 sourceSets { main { java.srcDirs = ['src/main'] // can be configured in different way assets.srcDirs = ['src/androidTest/assets'] // other things, examples res.srcDirs = ['res'] manifest.srcFile 'AndroidManifest.xml' } } 
Intereting Posts
Холст не рисует в пользовательском представлении Использование сканера штрих-кода Zxing вызывает SecurityException Меню Android: две однонаправленные группы в одном меню BaseAdapter приводит к тому, что ListView выйдет из строя при прокрутке Как добавить параметры в HTTP GET-запрос в Android? Ожидание намерения с разным намерением, но с тем же идентификатором Мое приложение Android Android теряет значения, хранящиеся в localStorage, когда он отключается. Кто-нибудь еще видит эту проблему? Ошибка при использовании Parse SDK для проверки PUSH-уведомлений. Несколько файлов dex определяют Lcom / parse / FacebookAuthenticationProvider $ 1 Xamarin.Android: как захватывать события Button, определенные в атрибуте XML OnClick? Как быть уверенным, что приложение Android будет работать на каждом устройстве Android Studio: разница между src / androidTest и src / основными папками? Элементы меню ActionBar исчезают в NestedFragments Как обнаружить события касания в определенной области Renderer в android? Как передать параметр веб-сервису с помощью ksoap2? Запуск приложений, содержащих большой объем кода