Skip to content

Instantly share code, notes, and snippets.

@venator85
Created September 6, 2016 10:43
Show Gist options
  • Save venator85/282df3677af9ecac56e5e4b91471cd8f to your computer and use it in GitHub Desktop.
Save venator85/282df3677af9ecac56e5e4b91471cd8f to your computer and use it in GitHub Desktop.
A Robolectric test runner for library projects compatible with Android Gradle plugin 2.2.0-alpha6 and later
import org.junit.runners.model.InitializationError;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
import org.robolectric.internal.bytecode.InstrumentationConfiguration;
import org.robolectric.manifest.AndroidManifest;
import org.robolectric.res.FileFsFile;
import org.robolectric.res.FsFile;
public class LibraryProjectTestRunner extends RobolectricTestRunner {
public LibraryProjectTestRunner(Class<?> klass) throws InitializationError {
super(klass);
}
@Override
protected AndroidManifest getAppManifest(Config config) {
AndroidManifest appManifest = super.getAppManifest(config);
FsFile androidManifestFile = appManifest.getAndroidManifestFile();
if (androidManifestFile.exists()) {
return appManifest;
} else {
androidManifestFile = FileFsFile.from(getModuleRootPath(config), appManifest.getAndroidManifestFile().getPath().replace("manifests/full", "manifests/aapt"));
return new AndroidManifest(androidManifestFile, appManifest.getResDirectory(), appManifest.getAssetsDirectory());
}
}
private String getModuleRootPath(Config config) {
String moduleRoot = config.constants().getResource("").toString().replace("file:", "");
return moduleRoot.substring(0, moduleRoot.indexOf("/build"));
}
}
@schnatterer
Copy link

Thanks for this!
You can make it more independent from the platform by replacing line 23 as follows

androidManifestFile = FileFsFile.from(getModuleRootPath(config), appManifest.getAndroidManifestFile().getPath().replace("manifests" + File.separator + "full", "manifests" + File.separator + "aapt"));

@GiorgioNatili
Copy link

It works like a charm, following a version that was written in Kotlin (with @schnatterer suggestion included) just in case someone else needs it:

import org.junit.runners.model.InitializationError
import org.robolectric.RobolectricTestRunner
import org.robolectric.annotation.Config
import org.robolectric.manifest.AndroidManifest
import org.robolectric.res.FileFsFile
import java.io.File

class LibraryGradleTestRunner @Throws(InitializationError::class)
constructor(klass: Class<*>) : RobolectricTestRunner(klass) {

    override fun getAppManifest(config: Config): AndroidManifest {

        val appManifest = super.getAppManifest(config)
        var androidManifestFile = appManifest.androidManifestFile

        if (androidManifestFile.exists()) {

            return appManifest
        } else {
            
            androidManifestFile = FileFsFile.from(getModuleRootPath(config), appManifest.androidManifestFile.path.replace("manifests" + File.separator + "full", "manifests" + File.separator + "aapt"))
            return AndroidManifest(androidManifestFile, appManifest.resDirectory, appManifest.assetsDirectory)
        }
    }

    private fun getModuleRootPath(config: Config): String {

        val moduleRoot = config.constants.java.getResource("").toString().replace("file:", "")
        return moduleRoot.substring(0, moduleRoot.indexOf("/build"))
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment