ProviderTestCase2 returns null on getMockContentResolver()

Issue

I’m using ProviderTestCase2 to test my ContentProvider, LinesCP, but calling getMockContentResolver() returns null.

The class path to LinesCP is ‘com.olfybsppa.inglesaventurero/start/LinesCP.java’. This is a segment of the code showing the AUTHORITY.

public class LinesCP extends ContentProvider {

  private static final String database_name  "lines.db";

  public static final String AUTHORITY  "com.olfybsppa.inglesaventurero.start.LinesCP";

I am running it using BuildVariants Unit Test, my other unit tests work. Here is the test that isn’t working.

public class ContentProviderUTest extends ProviderTestCase2<LinesCP>   {

  private static String ALPHABET  "AL-00";
  private MockContentResolver cr;

  public ContentProviderUTest () {
    super(LinesCP.class, "com.olfybsppa.inglesaventurero.start");
    //super(LinesCP.class, LinesCP.AUTHORITY);
  }

  public ContentProviderUTest (Class<LinesCP> providerClass, String providerAuthority) {
    super(providerClass, providerAuthority);
  }

  @Override
  protected void setUp() throws Exception {
    super.setUp();
    cr  getMockContentResolver(); // cr is null.
  }

  public void testSceneInsert() {
    Uri uri  LinesCP.sceneTableUri;
    ContentValues sceneValues  new ContentValues();
    sceneValues.put(LinesCP.scene_id, ALPHABET);
    sceneValues.put(LinesCP.english_title, "Alphabet");
    sceneValues.put(LinesCP.spanish_title, "Alphabeto");
    MockContentResolver cr  getMockContentResolver();
    Uri resultingUri  getMockContentResolver().insert(uri,   sceneValues);
    assertNotNull(resultingUri);
    long rowId  ContentUris.parseId(resultingUri);
    assertTrue(rowId > 0);
  }

}

I really think this should be working, any ideas welcome.

Solution

Quick Orientation: My ContentProvider is named LinesCP. LinesCP holds a table of CPHints. CPHint is my own class. My Test is ProviderInsertHintsTest which extends ProviderTestCase2

Even though ProviderTestCase2 does not inherit from InstrumentationTestCase, I am running ProviderInsertHintsTest using the Build Variants ‘Android Instrumentation Tests’. ProviderInsertHintsTest is in my src/androidTest/java/ folder. So, I previously thought ProviderTestCase2 should be run with BuildVariants ‘Unit Test’, and I think that was my main mistake.

In ProviderInsertHintsTest, I test LineCP’s insert(Uri, ContentValues) method. I get mMockResolver in setUp(). I use mMockResolver to insert a ContentValues I made from hint1. Then I use mMockResolver.query to get ‘fromCP’ back from the Content Provider. Then I assert that the original ‘hint1’ is equal to ‘fromCP’.

public class ProviderInsertHintsTest extends ProviderTestCase2<LinesCP> {

  private MockContentResolver mMockResolver;

  private CPHint hint1;
  private CPHint hint2;

  public ProviderInsertHintsTest() {
    super(LinesCP.class, LinesCP.AUTHORITY);
  }

  @Override
  protected void setUp() throws Exception {
    super.setUp();
    mMockResolver  getMockContentResolver();

    hint1  new CPHint(1);
    hint1.setNormalStartTime(1001);
    hint1.setNormalEndTime(1010);

    hint2  new CPHint(2);
    hint2.setNormalStartTime(2001);
    hint2.setNormalEndTime(2010);
  }

  @Override
  protected void tearDown() throws Exception {
    super.tearDown();
  }

  public void testInsertHint () {
    ContentValues cv  hint1.getContentValues(111);
    mMockResolver.insert(LinesCP.hintTableUri, cv);
    Cursor cursor  mMockResolver.query(LinesCP.hintTableUri, null, null, null, null);
    cursor.moveToFirst();
    assertEquals(1, cursor.getCount());
    CPHint fromCP  CPHint.extractCPHint(cursor);
    cursor.close();

    assertTrue(fromCP.equals(hint1));
  }

  public void testInsertTwoHintsDeleteOne () {
    ContentValues cv1  hint1.getContentValues(111);
    ContentValues cv2  hint2.getContentValues(111);

    mMockResolver.insert(LinesCP.hintTableUri, cv1);
    mMockResolver.insert(LinesCP.hintTableUri, cv2);

    Cursor cursor1  mMockResolver.query(LinesCP.hintTableUri, null, null, null, null);
    assertEquals(2, cursor1.getCount());
    cursor1.close();

    mMockResolver.delete(LinesCP.hintTableUri, Ez.where(BaseColumns._ID, "" + 1), null);
    Cursor cursor2  mMockResolver.query(LinesCP.hintTableUri, null, null, null, null);
    assertEquals(1, cursor2.getCount());
    cursor2.close();
  }
}

The only leap of faith is the CPHint.extractCPHint(Cursor cursor). It is only for drying up the code. It asks what is the value at LineCP’s column index that matches the column name, then creates a new CPHint. Here it is, just in case.

  public static CPHint extractCPHint(Cursor cursor) {
    Integer position  cursor.getInt(cursor.getColumnIndex(LinesCP.pos_id));
    CPHint hint  new CPHint(position);
    hint.setTimes(cursor.getLong(cursor.getColumnIndex(LinesCP.normal_start_time)),
      cursor.getLong(cursor.getColumnIndex(LinesCP.normal_end_time)),
    return hint;
  }

To test delete, I take mMockResolver and add hint1 and hint2 to the ContentProvider. Then I delete the CPHint that matches BaseColumns.ID equal to 1. Then I query the Content Provider again and assert that it only has one row, where as before it had two rows.

Answered By – flobacca

Leave a Comment