Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

is it possible to replace the MediaStore with a test double using robolectric?

I have a class that queries the MediaStore for images. For example, I have code that looks like someContentResolver.query( MediaStore.Images.Media.EXTERNAL_CONTENT_URI, ... ). I want to test that, among other things, my queries to the MediaStore are correct.

What I've done so far in my test is this:

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 );

I inject this resolver into my class, which performs a query on it. However, the query returns null. I saw this post: http://ikaruga2.wordpress.com/2013/07/29/roboelectric-and-contentresolverscontentproviders/ which says to register the content provider using ShadowContentResolver, so, something like:

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

but I don't know what to put for the content provider. Maybe use a MediaStore object? No, it is not a ContentProvider. Perhaps it is MediaProvider? The symbol can't be resolved, for some reason.

At this point I have serious doubts that this is even remotely the correct approach. Can someone steer me in the right direction?

using Robolectric 2.4 snapshot and API 19.

like image 727
Kevin Avatar asked Jul 05 '14 22:07

Kevin


1 Answers

You can rely on ShadowContentResolver.setCursor(Uri, BaseCursor) and RoboCursor to create test data and verify query. RoboCursor does not provide full implementation of a few methods, so you can either override and ignore them, or do something meaningful. RoboCursor extends BaseCursor, overriding setQuery() allows you to intercept queries and verify or do something there. Using 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);
like image 178
hidro Avatar answered Nov 14 '22 01:11

hidro