JUnit测试 - 进行测试的最佳和最可靠的方法?

时间:2014-03-27 09:34:55

标签: java unit-testing junit jsonassert

我正在使用JUnit测试我的Android应用。这是我第一次JUnit测试真实,所以我不知道我应该遵循的路径。现在我正在测试联系人列表中的查询。许多方法只需要Raw Contact IDContact ID作为参数,其中大部分都会返回JSON ObjectJSON ArrayArrayList

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

现在我正在测试它们:

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());
    }
}

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

有什么建议吗?改进?

2 个答案:

答案 0 :(得分:1)

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

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

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

在这种情况下,JUnit可能不是正确的工具; JMeter应该更好地满足这些需求。 以下是使用JMeter测试JSON数据的示例: Jmeter extracting fields/parsing JSON response

添加您的整合测试'连接SDLC中的实际数据源,但不应运行每个源构建/开发周期。你应该只运行集成测试'在部署时检查端到端集成。

答案 1 :(得分:0)

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