在Robolectric中使用多个res文件夹 [英] Using multiple res folders with Robolectric
问题描述
sourceSets {
androidTest {
setRoot('src / test')
}
main {
res.srcDirs =
[
'src / main / res / features / registration',
'src / main / res / features / login',
'src / main / res'
]
}
}
$ c $但是Robolectric允许我使用AndroidManifest配置一个目录:
public class RobolectricGradleTestRunner扩展了RobolectricTestRunner {
private static final int MAX_SDK_SUPPORTED_BY_ROBOLECTRIC = 18;
public RobolectricGradleTestRunner(Class<> testClass)引发InitializationError {
super(testClass);
$ b @Override
受保护的AndroidManifest getAppManifest(配置配置){
字符串manifestProperty =../app/src/main/AndroidManifest.xml;
String resProperty =../app/src/main/res;
返回新的AndroidManifest(Fs.fileFromPath(manifestProperty),Fs.fileFromPath(resProperty)){
@Override
public int getTargetSdkVersion(){
return MAX_SDK_SUPPORTED_BY_ROBOLECTRIC;
}
};
}
}
这种方式测试失败。是否可以配置robolectric以反映我的gradle文件?
解决方案
好的,这是最简单的方法,必须扩展 RobolectricTestRunner
getAppManifest
和 createAppResourceLoader
。
在 getAppManifest
中,您只需将清单存储在一个字段中,比如 mDefaultManifest
。
在createAppResourceLoader中,您必须添加注入的正确资源。
/ **
* TODO:注意:这是从Robolectric-2.4中的RobolectricTestRunner复制而来的,它保持最新!
* /
@Override
protected ResourceLoader createAppResourceLoader(ResourceLoader systemResourceLoader,AndroidManifest appManifest){
List< PackageResourceLoader> appAndLibraryResourceLoaders = new ArrayList< PackageResourceLoader>(); (ResourcePath resourcePath:appManifest.getIncludedResourcePaths()){
appAndLibraryResourceLoaders.add(createResourceLoader(resourcePath));
$ b $ * BEGIN EDIT * /
if(mDefaultManifest!= null){
ResourcePath rpInjected = new ResourcePath(mDefaultManifest.getRClass(),mDefaultManifest.getPackageName (),Fs.fileFromPath(../ app / src / main / res / features / registration),mDefaultManifest.getAssetsDirectory());
appAndLibraryResourceLoaders.add(createResourceLoader(rpInjected));
rpInjected = new ResourcePath(mDefaultManifest.getRClass(),mDefaultManifest.getPackageName(),Fs.fileFromPath(../ app / src / main / res / features / login),mDefaultManifest.getAssetsDirectory());
appAndLibraryResourceLoaders.add(createResourceLoader(rpInjected));
}
/ * END编辑* /
OverlayResourceLoader overlayResourceLoader = new OverlayResourceLoader(appManifest.getPackageName(),appAndLibraryResourceLoaders);
映射< String,ResourceLoader> resourceLoaders = new HashMap< String,ResourceLoader>();
resourceLoaders.put(android,systemResourceLoader);
resourceLoaders.put(appManifest.getPackageName(),overlayResourceLoader);
返回新的RoutingResourceLoader(resourceLoaders);
}
不要忘记添加 @RunWith(YourTestRunner。 class)
在你的测试类中。
My current Gradle configuration has multiple (Merged) res folders:
sourceSets {
androidTest {
setRoot('src/test')
}
main {
res.srcDirs =
[
'src/main/res/features/registration',
'src/main/res/features/login',
'src/main/res'
]
}
}
But Robolectric allows me to configure a single directory using AndroidManifest:
public class RobolectricGradleTestRunner extends RobolectricTestRunner {
private static final int MAX_SDK_SUPPORTED_BY_ROBOLECTRIC = 18;
public RobolectricGradleTestRunner(Class<?> testClass) throws InitializationError {
super(testClass);
}
@Override
protected AndroidManifest getAppManifest(Config config) {
String manifestProperty = "../app/src/main/AndroidManifest.xml";
String resProperty = "../app/src/main/res";
return new AndroidManifest(Fs.fileFromPath(manifestProperty), Fs.fileFromPath(resProperty)) {
@Override
public int getTargetSdkVersion() {
return MAX_SDK_SUPPORTED_BY_ROBOLECTRIC;
}
};
}
}
This way tests are failing. Is it possible to configure robolectric to reflect my gradle file?
Ok, this is the easiest way to do it, You will have to extend RobolectricTestRunner
getAppManifest
and createAppResourceLoader
.
In getAppManifest
you will simply have to store the manifest in a field, let's say mDefaultManifest
.
In createAppResourceLoader you will have to add the right resources injected.
/**
* TODO: Watch OUT this is copied from RobolectricTestRunner in Robolectric-2.4 keep it up to date!
*/
@Override
protected ResourceLoader createAppResourceLoader(ResourceLoader systemResourceLoader, AndroidManifest appManifest) {
List<PackageResourceLoader> appAndLibraryResourceLoaders = new ArrayList<PackageResourceLoader>();
for (ResourcePath resourcePath : appManifest.getIncludedResourcePaths()) {
appAndLibraryResourceLoaders.add(createResourceLoader(resourcePath));
}
/* BEGIN EDIT */
if(mDefaultManifest != null) {
ResourcePath rpInjected = new ResourcePath(mDefaultManifest.getRClass(), mDefaultManifest.getPackageName(), Fs.fileFromPath("../app/src/main/res/features/registration"), mDefaultManifest.getAssetsDirectory());
appAndLibraryResourceLoaders.add(createResourceLoader(rpInjected));
rpInjected = new ResourcePath(mDefaultManifest.getRClass(), mDefaultManifest.getPackageName(), Fs.fileFromPath("../app/src/main/res/features/login"), mDefaultManifest.getAssetsDirectory());
appAndLibraryResourceLoaders.add(createResourceLoader(rpInjected));
}
/* END EDIT */
OverlayResourceLoader overlayResourceLoader = new OverlayResourceLoader(appManifest.getPackageName(), appAndLibraryResourceLoaders);
Map<String, ResourceLoader> resourceLoaders = new HashMap<String, ResourceLoader>();
resourceLoaders.put("android", systemResourceLoader);
resourceLoaders.put(appManifest.getPackageName(), overlayResourceLoader);
return new RoutingResourceLoader(resourceLoaders);
}
Do not forget to add @RunWith(YourTestRunner.class)
in your test classes.
这篇关于在Robolectric中使用多个res文件夹的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!