is it possible to replace the MediaStore with a test double using robolectric?
android, android-contentprovider, android-contentresolver, robolectric
Solution
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);
Problem
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.