Android 单元测试中返回空游标的ContentResolver查询

Android 单元测试中返回空游标的ContentResolver查询,android,unit-testing,robolectric,Android,Unit Testing,Robolectric,我尝试在Android库中对我的db进行单元测试,下面是我的方法。提供者在清单中定义。我用RobolectrictTestRunner运行它 @RunWith(CustomRobolectricTestRunner.class) public class FileDatabaseTest { private ContentResolver contentResolver; @Before public void setUp() { Robolectric.buil

我尝试在Android库中对我的db进行单元测试,下面是我的方法。提供者在清单中定义。我用RobolectrictTestRunner运行它

    @RunWith(CustomRobolectricTestRunner.class)
public class FileDatabaseTest {

  private ContentResolver contentResolver;

  @Before
  public void setUp() {
    Robolectric.buildContentProvider(FileIndexContentProvider.class);
    contentResolver = RuntimeEnvironment.application.getContentResolver();


    FileDatabase fileDatabase = mock(FileDatabase.class);

    Mockito.doAnswer(new Answer() {
      public Object answer(InvocationOnMock invocation) {
        return null;
      }
    }).when(fileDatabase).close();
  }

  public void insertFileIndex() {
    ContentValues contentValues = new ContentValues();
    contentValues.put(FileContract.FileIndexTable.FILE_PATH, "path");
    contentValues.put(FileContract.FileIndexTable.FILENAME, "filename");
    contentValues.put(FileContract.FileIndexTable.STATUS, FileIndexEntry.FileStatus.ACTIVE.toString());
    contentValues.put(FileContract.FileIndexTable.CREATE_DATE, System.currentTimeMillis());
    contentResolver.insert(FileContract.FileIndexTable.CONTENT_URI, contentValues);
  }

  @Test
  public void testInsertFile() {
    insertFileIndex();
    Cursor cursor = contentResolver.query(FileContract.FileIndexTable.CONTENT_URI,
        FileContract.FileIndexTable.PROJECTION, null, null, null, null);
    assertNotNull(cursor);
    assertEquals(cursor.getCount(), 1);
    cursor.moveToFirst();
    FileIndexEntry fileIndexEntry = new FileIndexEntry(cursor);
    assertThat(fileIndexEntry.filename, equalTo("filename"));
  }
}
查询返回的游标为null。这发生在所有在db上工作的测试中

public class FileIndexContentProvider extends ContentProviderBase {

  private static final UriMatcher URI_MATCHER = new UriMatcher(UriMatcher.NO_MATCH);

  private static final int FILE_INDEX = 100;
  private static final int FILE_INDEX_ID = 101;

  static {
    URI_MATCHER.addURI(FileContract.AUTHORITY, FileIndexTable.TABLE_NAME, FILE_INDEX);
    URI_MATCHER.addURI(FileContract.AUTHORITY, FileIndexTable.TABLE_NAME + "/*", FILE_INDEX_ID);
  }

  /**
   * Static method to obtain table name from a Uri.
   */
  public static String tableForUri(Uri uri) {
    final int match = URI_MATCHER.match(uri);
    switch (match) {
      case FILE_INDEX:
      case FILE_INDEX_ID:
        return FileIndexTable.TABLE_NAME;
      default:
        throw new IllegalArgumentException("Unknown URI " + uri);
    }
  }

  @Override
  public boolean onCreate() {
    databaseHelper = new FileDatabase(getContext());
    return true;
  }

  @Override
  public String getTableForUri(Uri uri) {
    return tableForUri(uri);
  }

  @Override
  public String getType(@NonNull Uri uri) {
    final int match = URI_MATCHER.match(uri);
    switch (match) {
      case FILE_INDEX:
        return FileIndexTable.CONTENT_TYPE;
      case FILE_INDEX_ID:
        return FileIndexTable.CONTENT_ITEM_TYPE;
      default:
        throw new UnsupportedOperationException("Unknown uri: " + uri);
    }
  }
}

以下是ContentProvider代码。它在一个应用程序中测试得很好,但当我开始将它转移到库问题时,它就开始了。

为什么需要
CustomRunner
?您是否在日志中看到类似
AndroidManifest.xml的消息未找到?@EugenMartynov没有,我过去经常获取它们(查询仍然为空),但我让自定义runner获取清单并将其删除。通常,除非项目的布局是自定义的,否则您不需要自定义运行程序来访问清单。您可以共享提供商的代码吗?firebase的mock是如何注入内容提供商的?为什么需要
CustomRunner
?您是否在日志中看到类似
AndroidManifest.xml的消息未找到
?@EugenMartynov否,我过去是获取它们的(查询仍然为空),但我让CustomRunner获取清单并删除它们。通常,除非项目的布局是自定义的,否则您不需要自定义运行程序来访问清单。您可以共享提供商的代码吗?如何将firebase的模拟注入内容提供商?