Reputation: 3918
I am trying to unit test a function that takes a HashMap and concatenates the keys into a comma separated string. The problem is that when I iterate through the HashMap using entrySet (or keySet or valueSet) the values are not in the order I .put() them in. IE:
testData = new HashMap<String, String>(0);
testData.put("colA", "valA");
testData.put("colB", "valB");
testData.put("colC", "valC");
for (Map.Entry<String, String> entry : testData.entrySet()) {
System.out.println("TestMapping " + entry.getKey());
}
Gives me the following output:
TestMapping colB
TestMapping colC
TestMapping colA
The string created by the SUT is ColB,ColC,ColA
How can I unit test this, since keySet(), valueSet(), etc are somewhat arbitrary in their order?
This is the function I am trying to test:
public String getColumns() {
String str = "";
for (String key : data.keySet()) {
str += ", " + key;
}
return str.substring(1);
}
Upvotes: 0
Views: 3513
Reputation: 298409
There is no point in iterating over the HashMap
in this case. The only reason to iterate over it would be to construct the expected String
, in other words, perform the same operation as the method under test, so if you made an error implementing the method, you are likely to repeat the error when implementing the same for the unit test, failing to spot the error.
You should focus on the validity of the output. One way to test it, is to split it into the keys and check whether they match the keys of the source map:
testData = new HashMap<>();
testData.put("colA", "valA");
testData.put("colB", "valB");
testData.put("colC", "valC");
String result = getColumn();
assertEquals(testData.keySet(), new HashSet<>(Arrays.asList(result.split(", "))));
You are in control of the test data, so you can ensure that no ", "
appears within the key strings.
Note that in its current form, your question’s method would fail, because the result String
has an additional leading space. You have to decide whether it is intentional (in this case, you have to change the test to assertEquals(testData.keySet(), new HashSet<>(Arrays.asList(result.substring(1) .split(", "))));
) or a spotted bug (then, you have to change the method’s last line to return str.substring(2);
).
Don’t forget to make a testcase for an empty map…
Upvotes: 2
Reputation: 1445
HashMap does not maintain insertion order....If you want insertion order to be maintained use a linkedhashmap
Upvotes: 1