Technology

Roboelectric and ContentResolvers/ContentProviders


Setting up Roboelectric is dead simple. However, you may find that code like the one shown below doesn’t work:

//save using a task provider
Button saveButton = (Button) activity.findViewById(id.save_button);
saveButton.performClick();

//check that task was saved
ContentResolver resolver = activity.getContentResolver();
Cursor cursor = resolver.query(//...

//fails!
assertTrue(cursor != null);

Nothing gets saved to the mock in-memory database. Your break points in the ContentProvider don’t get called.

What gives?

Register the ContentProvider

In Roboelectric, you need to manually register your content provider. The code below does the trick:

//instantiate the ContentProvider directly
TaskProvider taskProvider = new TaskProvider();
taskProvider.onCreate();

//register the ContentProvider
ShadowContentResolver.registerProvider(TaskProvider.AUTHORITY_NAME, taskProvider);

Thanks to Vardhan for the tip!

Unimplemented Methods

We’re almost there. The default mock in-memory database is pretty cool. For basic CRUD, it works pretty much like a real database except that everything is stored in memory.

However, you might find that queries don’t work. The reason is that as of 7/27/2013, Android API 16 (which is the default version Roboelectric uses) adds a new database method that Roboelectric hasn’t implemented yet.

The solution is to…implement the missing method yourself. You have two options:

  • Add the missing method directly to shadow class. (Requires that you work directly with the Roboelectric source code).
  • Create a custom class in your test and bind it at runtime to the framework. (I haven’t figure out how to do that yet in Roboelectric 2.)

The offending class is ShadowSqlLiteDatabase. Add this method and you should be good:

@Implementation
public Cursor rawQueryWithFactory (SQLiteDatabase.CursorFactory cursorFactory,
                                 String sql,
                                 String[] selectionArgs,
                                 String editTable,
                                 CancellationSignal cancellationSignal)
{
  return rawQueryWithFactory(cursorFactory,
                             sql,
                             selectionArgs,
                             editTable);
}
Technology

Setup Roboelectric as a Submodule in Android Studio


Unit tests are awesome. In Android, the built-in unit tests are a kind of a drag because they require an emulator or a phone and APK deploys to the aforementioned device (in other words, they are slow). A popular alternative is Roboelectric. While it’s easy to add Roboelectric as a JAR or Maven dependency, it wasn’t so easy to add as a submodule.

“Why would you want Roboelectric as a submodule?” you ask.

Continue reading