是否可以使用robolectric将测试双重替换MediaStore?

Kev*_*vin 11 android android-contentresolver android-contentprovider robolectric

我有一个查询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 );
Run Code Online (Sandbox Code Playgroud)

我将这个解析器注入到我的类中,该类对它执行查询.但是,查询返回null.我看到这篇文章:http: //ikaruga2.wordpress.com/2013/07/29/roboelectric-and-contentresolverscontentproviders/ 表示使用ShadowContentResolver注册内容提供者,所以,如下所示:

ShadowContentResolver.registerProvider( MediaStore.AUTHORITY, <SOMETHING_GOES_HERE> );
Run Code Online (Sandbox Code Playgroud)

但我不知道该为内容提供商提供什么.也许用一个MediaStore对象?不,它不是ContentProvider.也许是这样MediaProvider?由于某种原因,该符号无法解析.

在这一点上,我严重怀疑这是远程正确的方法.有人能引导我朝着正确的方向前进吗?

使用Robolectric 2.4快照和API 19.

J.C*_*rro 0

我在 MediaStore 上遇到了类似的问题,在我的例子中,一个类尝试通过 ManagedQuery 访问 MediaStore。当运行经过此类代码路径的测试时,测试失败并出现 NPE,因为查询返回 null,就像您的情况一样。

违规方法

public String getPath(Uri uri, Activity activity) {
    String[] projection = { MediaColumns.DATA };
    Cursor cursor = activity
            .managedQuery(uri, projection, null, null, null);
    int column_index = cursor.getColumnIndexOrThrow(MediaColumns.DATA);
    cursor.moveToFirst();
    return cursor.getString(column_index);
}
Run Code Online (Sandbox Code Playgroud)

鉴于您已经注入(我在我的项目上使用 Dagger 注入依赖项)解析器,您可能想要模拟它(如果它适合您)(例如通过 Mockito),或者部分模拟它,因此有问题的方法默认为可用的返回值。

PhotoUtilities pu=Mockito.spy(new PhotoUtilities());
Mockito.doReturn(Constants.getDataDir().getAbsolutePath()+"/aaa.txt").
when(pu).getPath(Mockito.isA(Uri.class), Mockito.isA(Activity.class));  
Run Code Online (Sandbox Code Playgroud)

这样,当测试尝试运行时getPath(),它不会运行查询,而是使用部分模拟中设置的默认返回值,从而允许测试继续进行。

我知道它可能不是您真正想要的,但它可能适合您的需求,就像它适合我一样。