【问题标题】:Robolectric: Testing with ormliteRobolectric:使用 ormlite 进行测试
【发布时间】:2012-08-06 17:36:47
【问题描述】:

我正在尝试使用 robolectric 测试 ORMLite DAO,但数据库行为与在我的 Android 应用程序中使用时不同。我的 DAO 在 android 应用程序上运行良好。

阅读robolectric shadows和调试代码,遇到ShadowSQLiteOpenHelper(代码here)。

有谁知道这个影子是否足以测试 ormlite daos?或者我必须创造自己的影子来实现这一目标?这里有任何线索/提示/建议/示例吗?

提前致谢。


额外信息:

测试方法:

@Test
public void basicTest() throws SQLException {
    assertNotNull(randomStringResource); // Injection of an android resource: OK
    assertThat(randomStringResource, equalTo("Event")); // With correct value: OK
    assertNotNull(eventDao); // Dao injection: OK
    assertThat(eventDao.countOf(), equalTo(0L)); // Table empty: OK

    Event e1 = new Event("e1", new Date());
    eventDao.create(e1);

    assertNotNull(e1.getId()); // ID generated by OrmLite: OK
    assertThat(eventDao.countOf(), equalTo(1L)); // Table not empty: OK
    assertThat("e1", equalTo(eventDao.queryForId(e1.getId()).getName())); // Query for inserted event: Throws exception
}

运行此测试时遇到的一些问题:

  • 使用“camelCased”属性名称查询实体时出错:在测试的最后一行抛出错误 (related problem)。运行 Android 应用时从未遇到过这样的问题。
  • 当我将其中一个属性名称(例如,isEnabled 更改为 enabled)以避免驼峰问题时,之前的错误仍然存​​在......似乎内存数据库没有应用我所做的更改在实体上。

使用的版本:

  • Robolectric 1.1
  • OrmLite 4.41

【问题讨论】:

  • 如果不是"e1",那么事件的名称是什么?
  • 我假设您正在使用 Sqlite 进行测试。除非您生成自己的模式并且 db 字段名称与 Java 不匹配,否则我认为驼峰式的东西不是问题——区分大小写。
  • @Gray 此时,当查询要检索已保存的事件时,测试崩溃并出现异常。 QueryForId 不起作用,因为抛出了“camelCase 错误”。
  • @Gray 你是对的,我使用的是 SQLite,并且架构是从 MyDatabaseHelper.onCreate(..)(扩展 OrmLiteSqliteOpenHelper)自动生成的,带有 TableUtils.createTable(connectionSource, Event.class);
  • Jelies,你能接受flav给出的答案吗?它对我很有效。

标签: android testing dao ormlite robolectric


【解决方案1】:

很抱歉让你的话题复活了,但我遇到了同样的问题。

我正在使用 OrmLite 4.45 和 Robolectric 2.1。

ShadowSQLiteCursor.java 中,cacheColumnNames 方法对每个列名调用toLowerCase。所以我决定用我自己的(不叫toLowerCase)扩展ShadowSQLiteCursor

/**
* Simulates an Android Cursor object, by wrapping a JDBC ResultSet.
*/
@Implements(value = SQLiteCursor.class, inheritImplementationMethods = true)
public class ShadowCaseSensitiveSQLiteCursor extends ShadowSQLiteCursor {

private ResultSet resultSet;

public void __constructor__(SQLiteCursorDriver driver, String editTable, SQLiteQuery query) {}

/**
 * Stores the column names so they are retrievable after the resultSet has closed
 */
private void cacheColumnNames(ResultSet rs) {
    try {
        ResultSetMetaData metaData = rs.getMetaData();
        int columnCount = metaData.getColumnCount();
        columnNameArray = new String[columnCount];
        for(int columnIndex = 1; columnIndex <= columnCount; columnIndex++) {
            String cName = metaData.getColumnName(columnIndex);
            this.columnNames.put(cName, columnIndex - 1);
            this.columnNameArray[columnIndex - 1] = cName;
        }
    } catch(SQLException e) {
        throw new RuntimeException("SQL exception in cacheColumnNames", e);
    }
}
}

我的回答显然来得太晚了,但可能对其他人有所帮助!

【讨论】:

  • 它确实帮助了我。我将 @Config(shadows = {ShadowCaseSensitiveSQLiteCursor.class}) 添加到我的测试类
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多