我们试图从我们自己的内部Nexus存储库中使用org.robolectric:robolectric:3.0依赖.问题是Robolectric尝试从公共存储库(
as mentioned here)在运行时加载一些依赖项,并忽略build.gradle中的任何存储库覆盖.
由于我们无法从Intranet访问该公共位置,因此在尝试加载该依赖项后,我的测试会超时:
[WARNING] Unable to get resource
‘org.robolectric:android-all:jar:5.0.0_r2-robolectric-1’ from
repository sonatype (07001):
Error transferring file: Operation timed out
Robolectric configuration documentation的底部部分建议将其添加到Gradle配置中以覆盖URL:
- android {
- testOptions {
- unitTests.all {
- systemProperty 'robolectric.dependency.repo.url','https://local-mirror/repo'
- systemProperty 'robolectric.dependency.repo.id','local'
- }
- }
- }
不幸的是,我已经测试了,我从未看到系统属性被设置.我从我的自定义Robolectric跑步者(扩展RobolectricGradleTestRunner)中打印出来,并且系统属性保持设置为空.
- System.out.println("robolectric.dependency.repo.url: " + System.getProperty("robolectric.dependency.repo.url"));
我也尝试过类似于this comment的东西(但在RobolectricGradleTestRunner中不存在该方法),我也尝试直接在我的自定义Robolectric运行器中设置系统属性,这似乎没有帮助.
- @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 source code确实似乎确认存在这些系统属性.
解决方法
虽然不是直接使用属性的修复,但另一种让它工作的方法是在RobolectricTestRunner子类中重写getJarResolver()并将其指向工件主机:
- 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,因此在升级版本时应该小心.