Robolectric:使用ormlite进行测试

3
我正在尝试使用Robolectric测试ORMLite DAOs,但数据库行为与从我的Android应用程序中使用时不同。我的DAO在Android应用程序上完美地工作。
阅读有关Robolectric Shadows和调试代码的内容,我遇到了ShadowSQLiteOpenHelper(代码here)。
有人知道这个Shadow是否足以测试ORMLite DAOs吗?还是我必须创建自己的Shadow才能实现?这里有任何线索/提示/建议/示例吗?
提前致谢。

额外信息:

测试方法:

@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”属性名称的实体时出现错误:在测试的最后一行抛出错误(相关问题)。运行安卓应用程序从未遇到过这样的问题。
  • 当我更改了其中一个属性的名称(例如:isEnabled 更改为 enabled)以避免camelCase问题时,先前的错误仍然存在...似乎内存数据库没有应用我对实体所做的更改。

使用的版本:

  • Robolectric 1.1
  • OrmLite 4.41

我假设你在测试中使用Sqlite。我认为驼峰式命名不是问题,除非你生成了自己的模式并且数据库字段名称与Java不匹配(区分大小写)。 - Gray
@Gray,目前测试在查询保存的事件时会出现异常。QueryForId无法正常工作,因为会抛出“驼峰错误”。 - jelies
@Gray 你说得对,我正在使用SQLite,并且模式是从MyDatabaseHelper.onCreate(..)(它扩展了OrmLiteSqliteOpenHelper)自动生成的,使用TableUtils.createTable(connectionSource, Event.class); - jelies
你可能想在Android列表上发布,看看是否有人在此之前已经完成了这个。如果它仍然存在大小写问题,我怀疑这里是ORMLite的问题,尽管我不理解Robolectric:https://groups.google.com/forum/#!forum/ormlite-android - Gray
1
Jelies,你能接受Flav给出的答案吗?这对我非常有效。 - Christine
显示剩余5条评论
1个回答

6

抱歉打扰您的话题,但我遇到了同样的问题。

我使用的是OrmLite 4.45和Robolectric 2.1。

ShadowSQLiteCursor.java中,cacheColumnNames方法对每个列名都调用toLowerCase。因此,我决定使用自己的ShadowSQLiteCursor进行扩展(它不会调用toLowerCase):

/**
* 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);
    }
}
}

我的回答显然太晚了,但可能有助于其他人!


1
它确实帮了我。我在我的测试类中添加了@Config(shadows = {ShadowCaseSensitiveSQLiteCursor.class})。 - Christine

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接