使用多个 res 文件夹与 Robolectric



我当前的 Gradle 配置有多个(合并的(res 文件夹:

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

但是Robolectric允许我使用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;
            }
        };
    }
}

这样测试就会失败。是否可以配置机器人来反映我的 gradle 文件?

另一个类似于 Luca 的解决方案:

public class MyTestRunner extends RobolectricTestRunner {
    ...
    @Override
    protected AndroidManifest getAppManifest(Config config) {
        String appRoot = "./src/main/";
        String manifestPath = appRoot + "AndroidManifest.xml";
        String resDir = appRoot + "res";
        String assetsDir = appRoot + "assets";
        return new AndroidManifest(Fs.fileFromPath(manifestPath), Fs.fileFromPath(resDir), Fs.fileFromPath(assetsDir)) {
            @Override
            public List<ResourcePath> getIncludedResourcePaths() {
                List<ResourcePath> paths = super.getIncludedResourcePaths();
                paths.add(new ResourcePath(getRClass(), getPackageName(), Fs.fileFromPath("../app/src/main/res/features/registration"), getAssetsDirectory()));
                paths.add(new ResourcePath(getRClass(), getPackageName(), Fs.fileFromPath("../app/src/main/res/features/login"), getAssetsDirectory()));
                return paths;
            }
        };
    }
}

不要忘记用@RunWith(MyTestRunner.class)注释您的测试

好的,这是最简单的方法,您必须扩展RobolectricTestRunner getAppManifestcreateAppResourceLoader

getAppManifest中,您只需将清单存储在字段中,例如 mDefaultManifest .

在createAppResourceLoader中,您必须添加注入的正确资源。

/**
 * 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);
}

不要忘记在测试类中添加@RunWith(YourTestRunner.class)

最新更新