我正在使用JUnit
测试我的Android应用。这是我第一次JUnit
测试真实,所以我不知道我应该遵循的路径。现在我正在测试联系人列表中的查询。许多方法只需要Raw Contact ID
或Contact ID
作为参数,其中大部分都会返回JSON Object
,JSON Array
或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());
}
}
编码速度更快,但我需要手动从手机上下载数据库(对我来说不是什么大不了),并手动查询它以获取数据(不是很重要)但是它不是那么通用,如果数据库发生变化,我猜所有的测试都会失败。但我可以获取数据库的快照并保存它,然后始终对该快照执行测试。
有什么建议吗?改进?
答案 0 :(得分:1)
你应该看看Mockito:https://code.google.com/p/mockito/
基本上,您必须模拟数据源/服务接口游标/内容解析器并使用硬编码值(数据库快照的一些示例)实现它。 但是,只有在必须维护查询机制时才应该这样做;如果这超出了您的项目范围和/或没有动手,这将没有用。
对于testGetRelationship,这更多是关于集成测试:您在管道的一侧注入一些数据,并期望另一侧有相同的数据。
在这种情况下,JUnit可能不是正确的工具; JMeter应该更好地满足这些需求。 以下是使用JMeter测试JSON数据的示例: Jmeter extracting fields/parsing JSON response
添加您的整合测试'连接SDLC中的实际数据源,但不应运行每个源构建/开发周期。你应该只运行集成测试'在部署时检查端到端集成。
答案 1 :(得分:0)
单元测试是没有数据库或外部服务器的低级测试。您搜索的是集成测试甚至点击测试。