android - 是否可以使用 robolectric 将 MediaStore 替换为测试替身?

标签 android android-contentprovider robolectric android-contentresolver

我有一个类在 MediaStore 中查询图像。例如,我的代码看起来像 someContentResolver.query( MediaStore.Images.Media.EXTERNAL_CONTENT_URI, ... )。我想测试我对 MediaStore 的查询是否正确。

到目前为止,我在测试中所做的是:

ContentResolver resolver = new Activity().getContentResolver();
ContentValues values = new ContentValues();
values.put( MediaStore.Images.Media.DATA,
            "/fake/path/file1.jpg" );
values.put( MediaStore.Images.Media.DATE_ADDED,
            fakeTime.getTime() );
resolver.insert( MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                 values );

我将这个解析器注入(inject)到我的类中,它对其执行查询。但是,查询返回 null。我看到这个帖子:http://ikaruga2.wordpress.com/2013/07/29/roboelectric-and-contentresolverscontentproviders/它说要使用 ShadowContentResolver 注册内容提供者,因此,类似于:

ShadowContentResolver.registerProvider( MediaStore.AUTHORITY, <SOMETHING_GOES_HERE> );

但我不知道为内容提供者放什么。也许使用 MediaStore 对象?不,它不是 ContentProvider。也许是 MediaProvider?由于某种原因,无法解析该符号。

在这一点上,我严重怀疑这是否是正确的方法。有人可以引导我朝着正确的方向前进吗?

使用 Robolectric 2.4 快照和 API 19。

最佳答案

您可以信赖ShadowContentResolver.setCursor(Uri, BaseCursor)RoboCursor创建测试数据并验证查询。 RoboCursor 没有提供一些方法的完整实现,因此您可以覆盖并忽略它们,或者做一些有意义的事情。 RoboCursor 扩展 BaseCursor,覆盖 setQuery()允许您拦截查询并验证或在那里做一些事情。使用 Robolectric 3.0。

RoboCursor cursor = new RoboCursor() {
    @Override
    public void registerContentObserver(ContentObserver observer) {
        // no op
    }

    @Override
    public void unregisterContentObserver(ContentObserver observer) {
        // no op
    }

    @Override
    public void registerDataSetObserver(DataSetObserver observer) {
        // no op
    }

    @Override
    public void unregisterDataSetObserver(DataSetObserver observer) {
        // no op
    }

    @Override
    public boolean isClosed() {
        return true;
    }
};
cursor.setColumnNames(Arrays.asList(MediaStore.Images.Media._ID,
        MediaStore.Images.Media.BUCKET_DISPLAY_NAME));
cursor.setResults(new Object[][]{
        new Object[]{1L, "WhatsApp"},
        new Object[]{2L, "Photos"},
        new Object[]{3L, "WhatsApp"}
});
shadowOf(ShadowApplication.getInstance().getContentResolver())
        .setCursor(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, cursor);

关于android - 是否可以使用 robolectric 将 MediaStore 替换为测试替身?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24591119/

相关文章:

java - 元素不应重复

android - 使用proguard保持具有单个参数的方法

android - 三星设备在查询通话记录时返回短信

java - 在 Robolectric 测试中使用 Android KeyStore

java - Roboelectric 中的 IllegalStateException 与 SupportFragmentTestUtil.startVisibleFragment(myFragment)

android - iText 尝试创建 PDF 文件时出现问题

android - StableArrayAdapter 与 ArrayAdapter

java - 将提供者作为 Intent 的额外内容传递

android - ContentProvider 和 ContentResolver 应用程序是否都需要在内存中才能进行通信?

android - Gradle + Robolectric : Where do I put the file org. robolectric.Config.properties?