Test Resource Folder with Robolectric and Gradle

I want to add some test files to my test folder, because I want to simulate loading some JSON files. The problem is that the latest version of Robolectric (2.4) looks like it does not find the path of the test resources (I get NPE), but with Robolectric 2.3 it does.

This is what my project looks like:

enter image description here

In the Res class (used in tests), I load JSON this way:

public static String str(String path) throws IOException { InputStream is = null; try { is = Res.class.getResourceAsStream(path); // "is" IS NULL! return new String(ByteStreams.toByteArray(is)); // ERROR HERE } finally { if (is != null) { is.close(); } } } public static JsonReader json(String path) throws IOException { return new JsonReader(new StringReader(str("/contact.json"))); } 

And this is my build.gradle file:

 buildscript { // ... dependencies { classpath 'org.robolectric:robolectric-gradle-plugin:1.0.1' } } apply plugin: 'com.android.application' apply plugin: 'org.robolectric' robolectric { // ... include '**/*Test.class' ignoreFailures true // ... } android { compileSdkVersion 21 buildToolsVersion "22" defaultConfig { applicationId "com.ph" minSdkVersion 15 targetSdkVersion 21 versionCode 9 versionName '4.1' } sourceSets { androidTest { setRoot('src/test') res.srcDirs = [ 'src/test/resources' ] } test { setRoot('src/test') res.srcDirs = [ 'src/test/resources' ] } } } dependencies { compile 'com.android.support:support-v4:22.0.0' compile 'joda-time:joda-time:2.7' compile 'com.google.guava:guava:18.0' compile files('libs/gcm.jar') compile 'org.codehaus.jackson:jackson-core-asl:1.9.13' compile 'org.codehaus.jackson:jackson-mapper-asl:1.9.13' compile 'org.slf4j:slf4j-api:1.7.10' compile 'com.jakewharton:butterknife:6.1.0' provided 'com.squareup.dagger:dagger-compiler:1.2.2' compile 'com.squareup.dagger:dagger:1.2.2' // ================== TESTING LIBRARIES ====================== testCompile 'junit:junit:4.12' testCompile 'org.mockito:mockito-core:1.10.19' 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' } testCompile 'com.squareup:fest-android:1.0.+' testCompile 'org.bouncycastle:bcprov-jdk15on:1.50' testCompile 'com.jakewharton:butterknife:6.1.0' testCompile 'com.google.android:android:4.1.1.4' } 

And this error message:

 java.lang.NullPointerException at com.google.common.base.Preconditions.checkNotNull(Preconditions.java:210) at com.google.common.io.ByteStreams.copy(ByteStreams.java:65) at com.google.common.io.ByteStreams.toByteArray(ByteStreams.java:115) at com.ph.Res.str(Res.java:17) at com.ph.Res.json(Res.java:26) at com.ph.SyncTest.testContact(SyncTest.java:182) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26) at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27) at org.robolectric.RobolectricTestRunner$2.evaluate(RobolectricTestRunner.java:236) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) at org.robolectric.RobolectricTestRunner$1.evaluate(RobolectricTestRunner.java:158) at org.junit.runners.ParentRunner.run(ParentRunner.java:363) at org.junit.runner.JUnitCore.run(JUnitCore.java:137) at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:74) at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:211) at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:67) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134) 

Any idea what is wrong with Robolectric 2.4? Or is it better to roll back to 2.3?

+5
source share
1 answer

I think your problem is related to open problem in google. https://code.google.com/p/android/issues/detail?id=136013

There is also a workaround here is an unmodified copy from message # 10

 import groovy.json.StringEscapeUtils gradle.projectsEvaluated { def variants = android.applicationVariants.collect() tasks.withType(Test) { task -> try { variants.each { variant -> def buildTypeName = variant.buildType.name.capitalize() def productFlavorNames = variant.productFlavors.collect { it.name.capitalize() } if (productFlavorNames.isEmpty()) { productFlavorNames = [""] } def productFlavorName = productFlavorNames.join('') def flavor = StringUtils.uncapitalize(productFlavorName) def variationName = "${productFlavorName}${buildTypeName}" if (task.name.contains(variationName)) { def variationPath = variant.buildType.name; if (StringUtils.isNotEmpty(productFlavorName)) { variationPath = StringUtils.uncapitalize(productFlavorName) + "/" + variationPath } def copyTestResourcesTask = project.tasks.create("copyTest${variationName}Resources", Copy) copyTestResourcesTask.from("${projectDir}/src/test/resources") copyTestResourcesTask.into("${buildDir}/intermediates/classes/test/${variationPath}") // Makes the test task depend on the copy test resource variation task task.dependsOn(copyTestResourcesTask) variants.remove(variant) throw new Exception("Break") // Breaking the loop } } } catch (Exception e) {} // Just drop the exception } } 

and here you can find a working example https://github.com/nenick/android-gradle-template/blob/master/App/build.gradle

+2
source

Source: https://habr.com/ru/post/1215536/


All Articles