0

我正在使用JUnit. 这是我第一次JUnit进行真实测试,所以我不知道我应该遵循的路径。现在我正在测试对联系人列表的查询。许多方法只需要 aRaw Contact ID或 aContact ID作为参数,其中大多数要么返回 a JSON ObjectJSON Array要么返回 a ArrayList

我的问题是,我应该如何将我的预期结果与实际结果进行比较?

现在我正在像这样测试它们:

public void testGetRelationship() {
    JSONArray jsonArrayActual = new JSONArray();
    JSONArray jsonArrayExpected = new JSONArray();

    try {
        jsonArrayExpected = contact.getRelationship(RAW_CONTACT_ID);
    } catch (JSONException e) {
        e.printStackTrace();
        fail("Failed when calling the getRelationship method. " + e.getMessage());
    }

    Cursor cursor = getContext().getContentResolver().query(Data.CONTENT_URI, 
            new String[]{Relation.NAME, Relation.TYPE, Relation._ID, Relation.LABEL}, 
            Relation.RAW_CONTACT_ID + "=? AND " + Data.MIMETYPE + "=?", 
            new String[]{RAW_CONTACT_ID, Relation.CONTENT_ITEM_TYPE}, 
            null);

    if(cursor.moveToFirst())
    {
        do{ 
            try {
                final JSONObject jsonRelationshipObject = new JSONObject();

                final String name = cursor.getString(0);
                final Integer type = cursor.getInt(1);
                final Integer id = cursor.getInt(2);
                final String label = cursor.getString(3);

                jsonRelationshipObject.put("id", id);
                jsonRelationshipObject.put("type", type);
                jsonRelationshipObject.put("label", label);
                jsonRelationshipObject.put("name", name);

                jsonArrayActual.put(jsonRelationshipObject);
            } catch (JSONException e) {
                e.printStackTrace();
                fail("Failed while adding the values to the JSONObject. " + e.getMessage());
            }               
        } while(cursor.moveToNext());
    }
    else
    {
        cursor.close();
        fail("RawContact not found! ID: " + RAW_CONTACT_ID);
    }

    cursor.close();

    try {
        JSONAssert.assertEquals(jsonArrayExpected, jsonArrayActual, true);
    } catch (JSONException e) {
        e.printStackTrace();
        cursor.close();
        fail("JSONAssert exception: " + e.getMessage());
    }

}

基本上我正在调用我的真实方法并且几乎重新编码我的(正在测试的)方法。我觉得这没有效率,或者至少很无聊和乏味(再次编码我刚刚编码的内容)。我很确定有更好的方法来执行JUnit测试。我想自己查询联系人列表数据库并手动构建我的对象进行比较,如下所示:

public void testGetRelationship() {
    JSONArray jsonArrayActual = new JSONArray();
    JSONArray jsonArrayExpected = new JSONArray();

    try {
        jsonArrayExpected = contact.getRelationship(RAW_CONTACT_ID);
    } catch (JSONException e) {
        e.printStackTrace();
        fail("Failed when calling the getRelationship method. " + e.getMessage());
    }

    jsonRelationshipObject.put("id", 6);
    jsonRelationshipObject.put("type", 1);
    jsonRelationshipObject.put("label", "A label");
    jsonRelationshipObject.put("name", "the name");

    jsonArrayActual.put(jsonRelationshipObject);

    try {
        JSONAssert.assertEquals(jsonArrayExpected, jsonArrayActual, true);
    } catch (JSONException e) {
        e.printStackTrace();
        cursor.close();
        fail("JSONAssert exception: " + e.getMessage());
    }
}

编码速度更快,但缺点是我需要从手机手动下载数据库(对我来说没什么大不了的)并手动查询它以获取那里的数据(也不是什么大不了的事)但事实并非如此如此通用,如果数据库发生更改,我猜所有测试都会失败。但是我可以获取数据库的快照并保存它,然后始终在该快照上执行测试。

有什么建议么?改进?

4

2 回答 2

1

你应该看看 Mockito:https ://code.google.com/p/mockito/

基本上,您必须模拟您的数据源/服务接口游标/内容解析器并使用硬编码值(数据库快照的一些示例)实现它。但是只有在必须维护查询机制时才应该这样做;如果这超出了您的项目范围和/或没有动手,这将无济于事。

对于您的 testGetRelationship,这更多是关于集成测试:您在管道的一侧注入一些数据,并在另一侧期望相同的数据。

在这种情况下,JUnit 可能不是正确的工具;JMeter 应该更适合这些需求。这是使用 JMeter 测试 JSON 数据的示例: Jmeter 提取字段/解析 JSON 响应

在 SDLC 中添加连接真实数据源的“集成测试”,但这些测试不应运行每个源构建/开发周期。您应该只在部署时运行“集成测试”来检查端到端集成。

于 2014-03-27T10:31:11.943 回答
0

单元测试是没有数据库或外部服务器的低级测试。您搜索的是集成测试甚至点击测试。

于 2014-03-27T09:43:20.577 回答