在Robolectric中使用多个res文件夹 [英] Using multiple res folders with Robolectric

查看:229
本文介绍了在Robolectric中使用多个res文件夹的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  sourceSets {
androidTest {
setRoot('src / test')
}
main {
res.srcDirs =
[
'src / main / res / features / registration',
'src / main / res / features / login',
'src / main / res'
]
}
}


 

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆