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
后,您现在编写的每个测试都将与数据库的状态相对。
[测试Android数据库JUnit4风格](http://www.singhajit.com/testing-android-database/) – 2015-09-28 17:21:35