И ProviderTestCase
, и RenamingDelegatingContext
уничтожат базу данных, если она уже существует, прежде чем открывать ее в своем контексте, поэтому в этом смысле они оба используют один и тот же низкоуровневый подход к открытию базы данных SQLite.
Вы используете это, открывая базу данных в своем приборе в setUp()
, что обеспечит вашу работу со свежей базой данных перед каждым тестовым примером.
Я бы посоветовал вам пойти на написание поставщиков контента, а нечем создание адаптеров базы данных.Вы можете использовать общий интерфейс для доступа к данным, независимо от того, хранятся ли они в БД или где-то по сети, дизайн поставщиков контента может быть приспособлен для доступа к таким данным за счет небольшого количества накладных расходов IPC, что большинство из нас не должно 'не нужно заботиться.
Если бы вы сделали это для доступа к базе данных SQLite, среда полностью управляла бы для вас подключением к базе данных в отдельном процессе.Как добавлено, ProviderTestCase2<ContentProvider>
полностью загружает тестовый контекст для вашего контент-провайдера без необходимости написания одной строки кода.
Но это не значит, что это не такая уж большая работаСамозагрузка себя.Итак, предположим, что у вас был адаптер базы данных как таковой;мы просто сосредоточимся на open()
для получения доступа на запись в нашу базу данных, ничего особенного:
public class MyAdapter {
private static final String DATABASE_NAME = "my.db";
private static final String DATABASE_TABLE = "table";
private static final int DATABASE_VERSION = 1;
/**
* Database queries
*/
private static final String DATABASE_CREATE_STATEMENT = "some awesome create statement";
private final Context mCtx;
private SQLiteDatabase mDb;
private DatabaseHelper mDbHelper;
private static class DatabaseHelper extends SQLiteOpenHelper {
public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(DATABASE_CREATE_STATEMENT);
}
@Override
public void onUpgrade(SQLiteDatabase db, int a, int b) {
// here to enable this code to compile
}
}
/**
* Constructor - takes the provided context to allow for the database to be
* opened/created.
*
* @param context the Context within which to work.
*/
public MyAdapter(Context context) {
mCtx = context;
}
/**
* Open the last.fm database. If it cannot be opened, try to create a new
* instance of the database. If it cannot be created, throw an exception to
* signal the failure.
*
* @return this (self reference, allowing this to be chained in an
* initialization call)
* @throws SQLException if the database could be neither opened or created
*/
public MyAdapter open() throws SQLException {
mDbHelper = new DatabaseHelper(mCtx);
mDb = mDbHelper.getWritableDatabase();
return this;
}
public void close() {
mDbHelper.close();
}
}
Тогда вы можете написать свой тест следующим образом:
public final class MyAdapterTests extends AndroidTestCase {
private static final String TEST_FILE_PREFIX = "test_";
private MyAdapter mMyAdapter;
@Override
protected void setUp() throws Exception {
super.setUp();
RenamingDelegatingContext context
= new RenamingDelegatingContext(getContext(), TEST_FILE_PREFIX);
mMyAdapter = new MyAdapter(context);
mMyAdapter.open();
}
@Override
protected void tearDown() throws Exception {
super.tearDown();
mMyAdapter.close();
mMyAdapter = null;
}
public void testPreConditions() {
assertNotNull(mMyAdapter);
}
}
Итак, что происходитздесь то, что контекстная реализация RenamingDelegatingContext
, после вызова MyAdapter(context).open()
, всегда будет воссоздавать базу данных.Каждый тест, который вы пишете сейчас, будет идти против состояния базы данных после вызова MyAdapter.DATABASE_CREATE_STATEMENT
.