Sia il numero ProviderTestCase
e RenamingDelegatingContext
distruggeranno il database se ne esiste già uno prima di aprirlo nel suo contesto, quindi in questo senso hanno entrambi lo stesso approccio di basso livello verso l'apertura di un database SQLite.
È possibile sfruttare questo vantaggio aprendo il database nell'attrezzatura in setUp()
, che garantirà quindi il funzionamento con un nuovo database prima di ogni caso di test.
Suggerirei di andare a scrivere provider di contenuti invece di creare adattatori di database. È possibile utilizzare un'interfaccia comune per l'accesso ai dati, sia archiviata nel DB o da qualche parte sulla rete, la progettazione dei fornitori di contenuti può essere adattata per accedere a tali dati al costo di un po 'di spese generali IPC coinvolte che la maggior parte di noi non dovrebbe devo preoccuparmi di
Se l'accesso è stato eseguito per accedere a un database SQLite, il framework gestirà completamente la connessione al database in un processo separato. Come manzo aggiunto, lo ProviderTestCase2<ContentProvider>
avvia automaticamente un contesto di test per il provider di contenuti senza dover scrivere una singola riga di codice.
Ma, questo non è detto che non è uno sforzo enorme per fare il bootstrap te stesso. Quindi supponendo di avere un adattatore per database come tale; ci limiteremo a concentriamo su open()
per ottenere l'accesso in scrittura al nostro database, niente di speciale:
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();
}
}
allora si potrebbe scrivere il test in quanto tale:
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);
}
}
Quindi, cosa sta succedendo qui è che l'attuazione contesto di RenamingDelegatingContext
, una volta chiamato MyAdapter(context).open()
, verrà sempre ricreato il database. Ogni test che scrivi ora andrà contro lo stato del database dopo che è stato chiamato lo MyAdapter.DATABASE_CREATE_STATEMENT
.
[Test database Android in stile JUnit4] (http://www.singhajit.com/testing-android-database/) –