Как переопределить URL-адрес репозитория зависимостей Robolectric runtime?
мы пытаемся использовать org.robolectric:robolectric:3.0
зависимость от нашего собственного внутреннего репозитория Nexus. Проблема в том, что Robolectric пытается загрузить некоторые зависимости во время выполнения из общедоступного репозитория (как уже упоминалось здесь) и игнорирует любые переопределения репозитория в сборке.градля.
поскольку у нас нет доступа к этому общедоступному местоположению из нашей интрасети, мой тайм-аут тестов после попытки загрузить эту зависимость:
[предупреждение] не удается получить ресурс орг.robolectric: android-все: jar: 5.0.0_r2-робоэлектрик-1 ' из тип соната репозитория (https://oss.sonatype.org/content/groups/public/): Ошибка передачи файла: время ожидания операции
нижняя часть документация по конфигурации Robolectric рекомендует добавить это в конфигурацию Gradle, чтобы переопределить URL:
android {
testOptions {
unitTests.all {
systemProperty 'robolectric.dependency.repo.url', 'https://local-mirror/repo'
systemProperty 'robolectric.dependency.repo.id', 'local'
}
}
}
к сожалению, я проверил это, и я никогда не вижу, что системное свойство устанавливается. Я распечатал его изнутри моего пользовательского Robolectric runner (который распространяется RobolectricGradleTestRunner
) и это системное свойство остается равным null.
System.out.println("robolectric.dependency.repo.url: " + System.getProperty("robolectric.dependency.repo.url"));
Я также пытался сделать что-то похожее на комментарий (но этот метод не существует для переопределения в RobolectricGradleTestRunner
), и я также попытался установить свойства системы непосредственно в моем пользовательском Robolectric runner, и это, похоже, не помогло.
@Config(constants = BuildConfig.class)
public class CustomRobolectricRunner extends RobolectricGradleTestRunner {
private static final String BUILD_OUTPUT = "build/intermediates";
public CustomRobolectricRunner(Class<?> testClass) throws InitializationError {
super(testClass);
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"));
}
на исходный код Robolectric похоже, подтверждает, что эти системные свойства существуют.
3 ответов
хотя это не исправление для использования свойств напрямую, другой способ заставить это работать-переопределить getJarResolver()
на RobolectricTestRunner
подкласс и наведение его на ваш узел артефактов:
public final class MyTestRunner extends RobolectricTestRunner {
public MyTestRunner(Class<?> testClass) throws InitializationError {
super(testClass);
}
@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();
repository.setUrl("https://my-nexus.example.com/content/groups/public");
repository.setId("my-nexus");
dependenciesTask.addConfiguredRemoteRepository(repository);
dependenciesTask.setProject(project);
for (DependencyJar dependencyJar : dependencies) {
Dependency dependency = new Dependency();
dependency.setArtifactId(dependencyJar.getArtifactId());
dependency.setGroupId(dependencyJar.getGroupId());
dependency.setType(dependencyJar.getType());
dependency.setVersion(dependencyJar.getVersion());
if (dependencyJar.getClassifier() != null) {
dependency.setClassifier(dependencyJar.getClassifier());
}
dependenciesTask.addDependency(dependency);
}
dependenciesTask.execute();
@SuppressWarnings("unchecked")
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;
}
}
}
следует отметить, что это зависит от двух внутренних классов Robolectric, поэтому при обновлении версий следует проявлять осторожность.
вы можете установить свойства mavenRepositoryId
и mavenRepositoryUrl
of RoboSettings
, используемых MavenDependencyResolver
.
пример:
public class CustomRobolectricRunner extends RobolectricGradleTestRunner {
static {
RoboSettings.setMavenRepositoryId("my-nexus");
RoboSettings.setMavenRepositoryUrl("https://my-nexus.example.com/content/groups/public");
}
...
}
на связанный выпуск Github, одно исправление-настроить settings.xml
в своем :
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
<mirrors>
<mirror>
<id>jcenter</id>
<name>JCenter Remote</name>
<mirrorOf>*</mirrorOf>
<url>https://www.example.com/artifactory/jcenter-remote/</url>
</mirror>
</mirrors>
</settings>
<mirrorOf>*</mirrorOf>
кажется необходимым заставить Maven перенаправить все запросы репозитория на один удаленный. См.здесь для получения более подробной информации о настройках зеркала в Maven.
я обнаружил, что использование пульта Sonatype недостаточно, вы должны использовать пульт jcenter или Maven Central для получения всех транзитивных зависимости.