1

我当前的 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;
            }
        };
    }
}

这样测试就失败了。是否可以配置 robolectric 以反映我的 gradle 文件?

4

2 回答 2

4

另一个类似于 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)

于 2015-03-24T01:45:55.670 回答
2

好的,这是最简单的方法,您必须扩展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)您的测试类。

于 2014-12-23T11:57:07.917 回答