Как протестировать контент-провайдеры на Android
Я пытаюсь проверить свою БД с помощью ProviderTestCase2<T>
. Я вижу, как создается тестовая БД. Как я полагаю, тестируемый контент-провайдер должен использовать тестовую БД. Но как только я пробую любые вызовы против MockContentResolver
(или созданного с помощью newResolverWithContentProviderFromSql
), я получаю UnsupportedOperationException
. Это документировано для MockContentResolver как нормальное поведение. Поэтому я немного не уверен в цели ProviderTestCase2.
Как вы тестируете своих поставщиков контента?
Спасибо
Ответы
Ответ 1
Расширьте ProviderTestCase2, чтобы переопределить getMockContentResolver() и вернуть собственный класс, полученный из MockContentResolver.
public class MyProviderTestCase2 extends ProviderTestCase2 {
@Override
public MockContentResolver getMockContentResolver () {
return new MyMockContentResolver();
}
}
MyMockContentResolver должен будет переопределить любые методы, которые вы хотите протестировать в ContentProvider.
Затем вы должны иметь возможность запускать любые тесты, которые вы хотите получить у своего поставщика контента, в то время как он изолирован ProviderTestCase2
Ответ 2
Насколько я понял, настройка распознавателя образов не требуется явно - я мог бы наблюдать за случаями, где это возможно (возможно, правильное решение провайдера с помощью URI, hings, которым нужен corect getType()), но для меня, этого было достаточно, чтобы сделать что-то вроде этого:
package org.droidcon.apps.template.provider.test;
import org.droidcon.apps.template.provider.ProfileContract;
import org.droidcon.apps.template.provider.ProfileProvider;
import android.content.ContentProvider;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.test.ProviderTestCase2;
public class ProfileProviderTest extends ProviderTestCase2<ProfileProvider> {
public ProfileProviderTest() {
super(ProfileProvider.class, ProfileProvider.class.getName());
}
protected void setUp() throws Exception {
super.setUp();
}
/**
* Very basic query test.
*
* Prerequisites:
* <ul>
* <li>A provider set up by the test framework
* </ul>
*
* Expectations:
* <ul>
* <li> a simple query without any parameters, before any inserts returns a
* non-null cursor
* <li> a wrong uri results in {@link IllegalArgumentException}
* </ul>
*/
public void testQuery(){
ContentProvider provider = getProvider();
Uri uri = ProfileContract.CONTENT_URI;
Cursor cursor = provider.query(uri, null, null, null, null);
assertNotNull(cursor);
cursor = null;
try {
cursor = provider.query(Uri.parse("definitelywrong"), null, null, null, null);
// we're wrong if we get until here!
fail();
} catch (IllegalArgumentException e) {
assertTrue(true);
}
}
}
Ответ 3
Я добавляю эту запись, поскольку я думаю, что это может помочь программистам, которые хотят протестировать их контент-провайдера.
Представьте, что ваш контент-провайдер называется MyProvider и что у вас есть контрактный класс MyProviderContract, определяющий некоторые константы.
Прежде всего, вы напишете тестовый класс с именем MyProviderTestCase
, который наследуется от ProviderTestCase2<MyProvider>
. Вам нужно будет определить конструктор, который вызывается конструктором super
:
public MyProviderTestCase() {
super(MyProvider.class, MyProviderContract.AUTHORITY);
}
Затем вместо прямого использования вашего провайдера (избегайте использования getProvider()
, поскольку пользователи вашего провайдера контента не будут обращаться к нему напрямую), используйте getMockContentResolver()
, чтобы получить ссылку на контент-резольвер, а затем вызовите методы этот контент-резольвер (query
, insert
и т.д.). В следующем коде я покажу, как протестировать метод insert
.
public void testInsert() {
Uri uri = MyProviderContract.CONTENT_URI;
ContentValues values = new ContentValues();
values.put(MyProviderContract.FIELD1, "value 1");
values.put(MyProviderContract.FIELD2, "value 2");
Uri resultingUri = getMockContentResolver().insert(uri, values);
// Then you can test the correct execution of your insert:
assertNotNull(resultingUri);
long id = ContentUris.parseId(resultingUri);
assertTrue(id > 0);
}
Затем вы можете добавить столько методов тестирования, сколько хотите, используя контент-разрешение вместо поставщика контента напрямую, как и пользователи вашего поставщика контента.