title: How to set up Android's MockContentProvider
body: <p>I'm currently testing Android's ContentProvider and running into some issues mocking it. I've already spent days on the internet but didn't find any useful examples except of the introduction on the <a href="http://developer.android.com/tools/testing/contentprovider_testing.html" rel="nofollow">Android Developer Site</a>.</p>
  
  <p>I implemented a ContentProvider and wrote some tests. Everything works here completely fine.  The result of the tests are matching my expectations.</p>
  
  <pre><code>public class DirectMessageProviderTest extends ProviderTestCase2&lt;DirectMessageProvider&gt;{
  
      @SmallTest
      public void testInsert() {
          Log.d(TAG, "testInsert");
  
          /*
           * result retrieves twitterId for the newly inserted item
           */
          Uri result = provider.insert(
                  DirectMessageProvider.CONTENT_URI, 
                  createContentValues());
  
          Log.i(TAG, "INSERT; id for newly inserted item: " + result);
  
          assertNotNull("INSERT!!! failed", result);
  
          if (result != null) {
              isDirectMessageInserted = true;
          }
      }
  
      @SmallTest
      public void testQuery() {
          Log.d(TAG, "testQuery");
  
          Uri uri = Uri.withAppendedPath(
                  DirectMessageProvider.CONTENT_URI, 
                  String.valueOf(directMessage.getTwitterId()));
  
          /*
           * result retrieves a cursor or null
           */
          Cursor result = provider.query(
                  uri, 
                  null, 
                  null, 
                  null, 
                  null);
  
          Log.i(TAG, "QUERY; number of rows inside the cursor: " + result.getCount());
  
          int expected = isDirectMessageInserted ? 1 : 0;
  
          assertEquals("QUERY!!! failed", expected, result.getCount());
      }
  }
  </code></pre>
  
  <p>I also implemented a class which capsules the ContentProvider and provides more complex methods than delete, insert, query and update. Take a look!</p>
  
  <pre><code>public class DirectMessageDataAccessImpl implements
          DirectMessageDataAccessInterface {
  
      @Override
      public boolean isStored(TwitterDirectMessage directMessage)
              throws DataAccessException {
          Log.d(TAG, "isStored");
  
          try {
              Uri uri = Uri.withAppendedPath(
                      DirectMessageProvider.CONTENT_URI, 
                      String.valueOf(directMessage.getTwitterId()));
  
              Cursor cursor = resolver.query(
                      uri, 
                      null, 
                      null, 
                      null, 
                      null);
  
              cursor.moveToFirst();
  
              boolean result = (cursor.getCount() &gt; 0 ? true: false);
  
              cursor.close();
  
              return result;
          } catch (Exception e) {
              Log.e(TAG, e.getMessage(), e);
              throw new DataAccessException(e.getMessage());
          }
      }
  }
  </code></pre>
  
  <p>Finally we`re coming to my problem writing a test for this class. I want to write independent tests for this class using a mocked ContentResolver. I've found this [example] (http://www.androidadb.com/source/npr-android-app-read-only/Npr_Test/src/org/npr/android/util/PlaylistProviderTest.java.html) on the internet and tried to use MockContentResolver. </p>
  
  <p>First of all, I created a new ContentProvider which will retrieve the delete, insert, query and update calls from the tested class, to create the same answer again and again.</p>
  
  <pre><code>public class DirectMessageDataAccessTest extends ProviderTestCase2&lt;DirectMessageProvider&gt;{
  
      private ContentProvider provider = new ContentProvider() {
  
          @Override
          public int update(Uri uri, ContentValues values, String selection,
                  String[] selectionArgs) {
              Log.d(TAG, "update");
              return 0;
          }
  
          @Override
          public Cursor query(Uri uri, String[] projection, String selection,
                  String[] selectionArgs, String sortOrder) {
              Log.w(TAG, "query");
              return null;
          }
  
          @Override
          public boolean onCreate() {
              Log.d(TAG, "onCreate");
              return false;
          }
  
          @Override
          public Uri insert(Uri uri, ContentValues values) {
              Log.d(TAG, "insert");
              return null;
          }
  
          @Override
          public String getType(Uri uri) {
              Log.d(TAG, "getType");
              return null;
          }
  
          @Override
          public int delete(Uri uri, String selection, String[] selectionArgs) {
              Log.d(TAG, "delete");
              return 0;
          }
      };
  }
  </code></pre>
  
  <p>After this, I modified my setUp Method in order to create a MockContentResolver and added my ContentProvider above</p>
  
  <pre><code>@Override
  protected void setUp() throws Exception {
      super.setUp();
  
      /*
       * MockContentResolver overrides Android's normal way of resolving providers by authority
       */
      MockContentResolver resolver = new MockContentResolver();
  
      /*
       * Adds access to a provider based on its authority
       */
      resolver.addProvider(DirectMessageProvider.AUTHORITY, provider);        
  
      context = new IsolatedContext(resolver, getContext());
  
      this.setContext(context);
  }
  </code></pre>
  
  <p>Last but not least, I wrote a test case for my isStored Method.</p>
  
  <pre><code>public void testIsStored() {
      Log.d(TAG, "testIsStored");
  
      TwitterDirectMessage directMessage = new TwitterDirectMessage();
  
      directMessage.setTwitterId(123456);
  
      DirectMessageDataAccessInterface dataAccess = 
              new DirectMessageDataAccessImpl(context);
  
      try {
          assertFalse(dataAccess.isStored(directMessage));
      } catch (DataAccessException e) {
          e.printStackTrace();
          fail("...");
      }
  }
  </code></pre>
  
  <p>Unfortunately, android.content.ContentProvider always throws a NullPointerException. I'm calling <code>resolver.query(...)</code>in line 72 of DirectMessageDataAccessImpl</p>
  
  <pre><code>E/DirectMessageDataAccessImpl(1758): null
  E/DirectMessageDataAccessImpl(1758): java.lang.NullPointerException
  E/DirectMessageDataAccessImpl(1758):    at android.content.ContentProvider$Transport.enforceReadPermission(ContentProvider.java:284)
  E/DirectMessageDataAccessImpl(1758):    at android.content.ContentProvider$Transport.query(ContentProvider.java:177)
  E/DirectMessageDataAccessImpl(1758):    at android.content.ContentResolver.query(ContentResolver.java:311)
  E/DirectMessageDataAccessImpl(1758):    at xxx.xxxxx.xxxxxxx.app.database.dataaccess.implementation.DirectMessageDataAccessImpl.isStored(DirectMessageDataAccessImpl.java:72)
  E/DirectMessageDataAccessImpl(1758):    at xxx.xxxxx.xxxxxxx.app.test.dataaccess.DirectMessageDataAccessTest.testIsStored(DirectMessageDataAccessTest.java:107)
  </code></pre>