2015-03-17 17 views
5

Chcę dodać kilka plików testowych do mojego folderu testowego, ponieważ chcę zasymulować załadowanie niektórych plików JSON. Problem polega na tym, że ostatnia wersja Robolectric (2.4) wygląda tak, jakby nie znajdowała ścieżki test-resources (otrzymuję NPE), ale Robolectric 2.3 to robi.Folder zasobów testowych z Robolectric i Gradle

To jest jak mój projekt wygląda tak:

enter image description here

W klasie Res (stosowane w testach), załadować JSON w ten sposób:

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"))); 
} 

I to jest moje plik build.gradle:

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' 
} 

I to jest komunikat o błędzie:

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) 

Jakieś pojęcie, co jest nie tak z Robolectric 2.4? A może lepiej wycofać do wersji 2.3?

Odpowiedz

2

Zgaduję, że Twój problem jest związany z otwartym problemem w Google. https://code.google.com/p/android/issues/detail?id=136013

Istnieją również obejście tutaj niezmienioną kopię z postu # 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 
} 
} 

i tutaj można znaleźć pracy przykład https://github.com/nenick/android-gradle-template/blob/master/App/build.gradle