在Robolectric中测试SQLite数据库

Kje*_*ide 17 sqlite android robolectric

我正试图在我的Android应用程序中使用Robolectric测试一个简单的SQLite数据库.我正在输入一些值,但在读取它们时会返回0行.

我正在使用SQLiteOpenHelper类来访问数据库.

// RequestCache extends SQLiteOpenHelper
RequestCache cache = new RequestCache(activity); 
SQLiteDatabase db = cache.getWritableDatabase();

// Write to DB
ContentValues values = new ContentValues();
values.put(REQUEST_TIMESTAMP, TEST_TIME); 
values.put(REQUEST_URL, TEST_URL);
db.insertOrThrow(TABLE_NAME, null, values);

// Read from DB and compare values      
Vector<Request> matchingRequests = new Vector<Request>();
db = cache.getReadableDatabase();
Cursor cursor = db.query(TABLE_NAME, SEARCH_URL_RETURN_COLUMNS, SEARCH_URL_WHERE, new String[] {url}, null, null, ORDER_BY, null);
int id = 0;

while(cursor.moveToNext()) {
    long timestamp = cursor.getLong(0);
    Request request = new Request(id++);
    request.setUrl(url);
    request.setCreationTimestamp(new Date(timestamp));
    matchingRequests.add(request);
}


// Assert that one row is returned
assertThat(matchingRequests.size(), equalTo(1));  // fails, size() returns 0
Run Code Online (Sandbox Code Playgroud)

在robolectric之外调试代码时,这可以按预期工作.我做错了什么或是不可能使用Robolectric测试SQlite数据库?

Jev*_*vll 19

Robolectric 2.3使用SQLite的真实实现,而不是阴影和假货的集合.现在可以编写测试来验证真实的数据库行为.

  • 你能举个例子吗?与旧测试代码相比,这在代码中看起来如何? (2认同)

Wal*_*tsu 10

注意:此答案已过时.如果您使用的是Roboletric 2.X,请参阅/sf/answers/1720483271/

问题是Robolectric的SQLiteDatabase只存储在内存中,因此当您调用getReadableDatabase或getWritableDatabase时,现有数据库将被新的空数据库覆盖.

我遇到了同样的问题,我发现只有解决方案是我需要分叉Robolectric项目并添加ShadowSQLiteOpenHelper来保存数据库,如果给出两次相同的上下文.然而,我的fork的问题是我必须在给出contex时'禁用'close() - 函数,否则Connection.close()会破坏内存中的数据库.我已经为它做了拉取请求,但它尚未合并到项目中.

但随意克隆我的版本,它应该解决你的问题(如果我理解正确:P).它可以在GitHub上找到:https://github.com/waltsu/robolectric

以下是如何使用修改的示例:

Context c = new Activity(); 
SQLiteOpenHelper helper = new SQLiteOpenHelper(c, "path", null, 1); 
SQLiteDatabase db = helper.getWritableDatabase(); 
// With the db write something to the database 
db.query(...); 
SQLiteOpenHelper helper2 = new SQLiteOpenHelper(c, "path", null, 1); 
SQLitedatabase db2 = helper2.getWritableDatabase(); 
// Now db and db2 is actually the same instance 
Cursor c = db2.query(...) ; // Fetch the data which was saved before 
Run Code Online (Sandbox Code Playgroud)

当然,您不需要创建新的SQLiteOpenHelper,但这只是将相同的上下文传递给两个不同的SQLiteOpenHelper的示例,它们将提供相同的数据库.