Comment accéder aux fichiers du dossier assets pendant l'exécution des tests unitaires? Mon projet est construit avec Gradle, j'utilise Robolectric pour exécuter des tests. Il semble que Gradle reconnaisse la assets
:
Voici comment j'ai du mal à lire le fichier:
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);
}
Mais stream
est toujours null
. Je l’ai essayé de différentes manières, c’est-à-dire le chemin défini vers un fichier en utilisant différentes approches.
Merci beaucoup d'avance.
Fondamentalement, vous devez utiliser Context
pour lire les actifs. Vous ne pouvez pas charger d'actifs avec ClassLoader
car ce n'est pas dans un chemin de classe. Je ne suis pas sûr de savoir comment vous exécutez les cas de test Robolectric. Voici comment je peux réaliser à la fois dans Android studio et dans la commande gralde.
J'ai ajouté un module de test d'unité d'application distinct pour exécuter les scénarios de test Robolectric dans un projet d'application. Avec une configuration de construction appropriée et une variable RobolectricTestRunner
personnalisée, le scénario de test suivant est accepté.
@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);
}
}
app-unit-test/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')
}
Ajoutez RobolectricTestRunner personnalisé pour ajuster les chemins de fichiers. Consultez le chemin des ressources.
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);
}
}
J'ai suivi ce blog pour le faire.
Des exemples de codes complets sont ici .
Je viens de me retrouver avec le même problème et voici comment cela fonctionne pour moi.
Je mets les fichiers de test dans le dossier src/test/resources
au lieu du dossier assets.
Ensuite, je reçois ces fichiers comme flux de la manière suivante
private InputStream openFile(String filename) throws IOException {
return getClass().getClassLoader().getResourceAsStream(filename);
}
filename
est le chemin relatif du fichier dans le dossier resources
.
C'est tout. J'ai trouvé la solution chez Robolectric github
Mise à jour comme pour 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);
}
Voir également
de Guide
Avec le dernier test d'instrumentation Android, vous pouvez simplement utiliser ceci:
InstrumentationRegistry.getContext().getAssets().open(filePath);
Lorsque Robolectric, nous devons tenir compte de ce qui suit:
Par défaut, Robolectric supposera que vos ressources et vos actifs se trouvent dans des répertoires nommés respectivement res et assets. Ces chemins sont supposés être relatifs au répertoire où se trouve le manifeste. Vous pouvez modifier ces valeurs en ajoutant les options resourceDir et assetDir à l'annotation @Config.
Voir le fonctionnaire docs
Avez-vous essayé de placer le dossier des actifs sous main au lieu de androidTest?
En outre, utilisez-vous https://github.com/robolectric/robolectric-gradle-plugin pour exécuter vos tests?