How to specify classpath ordering in Gradle

后端 未结 2 2063
你的背包
你的背包 2021-01-11 15:23

I need to control the ordering of jars in the testRuntime configuration.

I must make sure that robolectric-x.x.jar comes before android.jar, or else I get the dreade

相关标签:
2条回答
  • 2021-01-11 15:48

    Here is my complete build.gradle for running Robolectric tests against my Android app, which uses RoboGuice:

    apply plugin: 'java'
    
    androidJar = new File(System.getenv('ANDROID_HOME'), '/platforms/android-7/android.jar')
    
    configurations { robo }
    
    dependencies {
        robo('com.pivotallabs:robolectric:1.0-RC1')
        testCompile('org.roboguice:roboguice:1.1.2')
        testCompile('junit:junit:4.8.2')
        testCompile project (':app')
        testCompile files(androidJar)
    }
    
    sourceSets.test.compileClasspath = configurations.robo + sourceSets.test.compileClasspath
    sourceSets.test.runtimeClasspath = configurations.robo + sourceSets.test.runtimeClasspath
    
    test {
        excludes = ['**/MyRobolectricTestRunner.class']
    }
    

    I had to add an exclusion for the test runner, or else Gradle will throw an exception.

    MyRobolectricTestRunner.java looks like this:

    package com.acme.myapp;
    
    import java.io.File;
    import org.junit.runners.model.InitializationError;
    import roboguice.application.RoboApplication;
    import roboguice.inject.ContextScope;
    import com.google.inject.Injector;
    import com.xtremelabs.robolectric.Robolectric;
    import com.xtremelabs.robolectric.RobolectricTestRunner;
    
    public class MyRobolectricTestRunner extends RobolectricTestRunner {
        public MyRobolectricTestRunner(Class<?> testClass) throws InitializationError {
            // Tell Robolectric where to find AndroidManifest.xml and res/
            super(testClass, new File("../app"));
        }
    
        /**
         * Enable injection into tests as well...
         */
        @Override
        public void prepareTest(Object test) {
            RoboApplication myApplication = (RoboApplication) Robolectric.application;
            Injector injector = myApplication.getInjector();
            ContextScope contextScope = injector.getInstance(ContextScope.class);
            contextScope.enter(myApplication);
            injector.injectMembers(test);
        }
    
    }
    

    And here's a sample test that illustrates injection:

    package com.acme.myapp;
    
    import static org.junit.Assert.assertEquals;
    
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import roboguice.inject.InjectResource;
    
    @RunWith(MyRobolectricTestRunner.class)
    public class StringFormattingTest {
    
        @InjectResource(R.string.info_pending_amount)
        private String pendingAmountPattern;
    
        @Test
        public void testFormatInfoPendingAmount() {
            String s = String.format(pendingAmountPattern, 20.0d, "EUR");
            assertEquals("Only a part of your stake (20,00 EUR) was accepted", s);
        }
    
    }
    
    0 讨论(0)
  • 2021-01-11 15:48

    This might work:

    configurations { robo }
    
    dependencies {
      robo ...
      testRuntime ...
    }
    
    sourceSets.test.runtimeClasspath = configurations.robo + sourceSets.test.runtimeClasspath
    
    0 讨论(0)
提交回复
热议问题