Dan J Dan J - 4 months ago 27
Android Question

How to override the Robolectric runtime dependency repository URL?

We're trying to use the

dependency from our own internal Nexus repository. The issue is that Robolectric tries to load some dependencies at runtime from a public repository (as mentioned here), and ignores any repository overrides in the build.gradle.

Since we don't have access to that public location from our intranet, my tests timeout after trying to load that dependency:

[WARNING] Unable to get resource
'org.robolectric:android-all:jar:5.0.0_r2-robolectric-1' from
repository sonatype (https://oss.sonatype.org/content/groups/public/):
Error transferring file: Operation timed out

The bottom section of the Robolectric configuration documentation recommends adding this to your Gradle configuration to override the URL:

android {
testOptions {
unitTests.all {
systemProperty 'robolectric.dependency.repo.url', 'https://local-mirror/repo'
systemProperty 'robolectric.dependency.repo.id', 'local'

Unfortunately, I've tested that and I never see that system property being set. I've printed it out from inside my custom Robolectric runner (which extends
) and that system property remains set to null.

System.out.println("robolectric.dependency.repo.url: " + System.getProperty("robolectric.dependency.repo.url"));

I also tried to do something similar to this comment (but that method doesn't exist to override in
), and I also tried setting the system properties directly in my custom Robolectric runner, and that didn't seem to help.

@Config(constants = BuildConfig.class)
public class CustomRobolectricRunner extends RobolectricGradleTestRunner {
private static final String BUILD_OUTPUT = "build/intermediates";

public CustomRobolectricRunner(Class<?> testClass) throws InitializationError {

System.setProperty("robolectric.dependency.repo.url", "https://nexus.myinternaldomain.com/content");
System.setProperty("robolectric.dependency.repo.id", "internal");

System.out.println("robolectric.dependency.repo.url: " + System.getProperty("robolectric.dependency.repo.url"));

The Robolectric source code does seem to confirm that these system properties exist.


While not a fix for using the properties directly, another way to get this to work is by overriding getJarResolver() in a RobolectricTestRunner subclass and pointing it at your artifact host:

public final class MyTestRunner extends RobolectricTestRunner {
  public MyTestRunner(Class<?> testClass) throws InitializationError {

  @Override protected DependencyResolver getJarResolver() {
    return new CustomDependencyResolver();

  static final class CustomDependencyResolver implements DependencyResolver {
    private final Project project = new Project();

    @Override public URL[] getLocalArtifactUrls(DependencyJar... dependencies) {
      DependenciesTask dependenciesTask = new DependenciesTask();
      RemoteRepository repository = new RemoteRepository();
      for (DependencyJar dependencyJar : dependencies) {
        Dependency dependency = new Dependency();
        if (dependencyJar.getClassifier() != null) {

      Hashtable<String, String> artifacts = project.getProperties();
      URL[] urls = new URL[dependencies.length];
      for (int i = 0; i < urls.length; i++) {
        try {
          urls[i] = Util.url(artifacts.get(key(dependencies[i])));
        } catch (MalformedURLException e) {
          throw new RuntimeException(e);
      return urls;

    @Override public URL getLocalArtifactUrl(DependencyJar dependency) {
      URL[] urls = getLocalArtifactUrls(dependency);
      if (urls.length > 0) {
        return urls[0];
      return null;

    private String key(DependencyJar dependency) {
      String key =
          dependency.getGroupId() + ":" + dependency.getArtifactId() + ":" + dependency.getType();
      if (dependency.getClassifier() != null) {
        key += ":" + dependency.getClassifier();
      return key;

It should be noted that this relies on two internal classes of Robolectric so care should be taken when upgrading versions.