I'm testing my android app using JUnit
. It's the first time I do JUnit
testing for real so I don't know the path I should follow. Right now I'm testing the queries to the contacts list. Many methods just require a Raw Contact ID
or a Contact ID
as a parameter and most of them either return a JSON Object
, JSON Array
or an ArrayList
.
My question is, how should I compare my expected result with the actual result?
Right now I'm testing them like this:
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());
}
}
Basically I'm calling my real method and pretty much re-coding my (under test) method. I find this unproductive or at least quite boring and tedious (coding again what I just coded sometime ago). I'm quite sure there is a better way to perform JUnit
tests. I thought about myself querying the contact list database and hand build my object to compare, something like this:
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());
}
}
It is faster to code but the drawn back is I need to manually download the database from the phone (not a big deal for me) and manually query it to get the data in there (not a big deal as well) but it is not so generic, if the database changes I guess all the tests will fail. But I can get a snapshot of the database and save it and then always perform the tests on that snapshot.
Any suggestions? Improvements?