我目前正在測試Android的ContentProvider,並遇到一些嘲笑它的問題。我已經在互聯網上花了幾天時間,但除了Android Developer Site的介紹外沒有找到任何有用的例子。如何設置Android的MockContentProvider
我實現了一個ContentProvider並編寫了一些測試。一切工作在這裏都很好。測試結果符合我的期望。
public class DirectMessageProviderTest extends ProviderTestCase2<DirectMessageProvider>{
@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());
}
}
我還實現了一個包含ContentProvider的類,並提供比刪除,插入,查詢和更新更復雜的方法。看一看!
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() > 0 ? true: false);
cursor.close();
return result;
} catch (Exception e) {
Log.e(TAG, e.getMessage(), e);
throw new DataAccessException(e.getMessage());
}
}
}
最後我們來談談我的問題,爲這堂課寫作測試。我想使用模擬的ContentResolver爲這個類編寫獨立的測試。我發現這個[示例](http://www.androidadb.com/source/npr-android-app-read-only/Npr_Test/src/org/npr/android/util/PlaylistProviderTest.java.html)互聯網,並試圖使用MockContentResolver。
首先,我創建了一個新的ContentProvider,它將從受測試的類中檢索刪除,插入,查詢和更新調用,從而一次又一次地創建相同的答案。
public class DirectMessageDataAccessTest extends ProviderTestCase2<DirectMessageProvider>{
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;
}
};
}
在此之後,我修改我的設置方法,以創造一個MockContentResolver並添加上述
@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);
}
最後但並非最不重要的,我寫了一個測試案例我isStored方法我的ContentProvider。
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("...");
}
}
不幸的是,android.content.ContentProvider總是拋出一個NullPointerException。我在DirectMessageDataAccessImpl
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)
有什麼辦法注入我自己的提供者以獲得靜態結果?只要我添加'addProvider',我就會得到上面的NullPointerException。 –
你在這裏添加你自己的提供者 - > super(DBProvider.class,「com.yourpackage.main」); MockContentResolver將繼續引用您的提供者 – Yahor10