2.3. Unit Testing
Robustness tests.
Auxiliary Method
Let us create PriorityQueueTest
and define testRobustnessAux()
that checks the robustness of any PQ inheriting AbstractPriorityQueue
:
/**
* @param pq a priority queue.
* @param keys a list of comparable keys.
* @param comp a comparator used for sorting.
*/
<T extends Comparable<T>> void testRobustness(AbstractPriorityQueue<T> pq, List<T> keys, Comparator<T> comp) {
keys.forEach(pq::add);
keys = keys.stream().sorted(comp).collect(Collectors.toList());
keys.forEach(key -> assertEquals(key, pq.remove()));
}
L6
: the generic typeT
is defined specifically for this method such that the priority queuepq
, the listkeys
, and the comparatorcomp
take the same typeT
that is comparable.L9
: iterates each of the sorted keys and compares it to the returned value ofpq.remove()
.
What are the advantages of defining a method-level generic type?
Functional Programming
The following code shows a traditional way of iterating over a list (that is equivalent to L7
above):
for (int i=0; i<keys.size(); i++)
pq.add(keys.get(i));
Java 5 introduced an enhanced for loop that simplified the traditional for loop:
for (T key : keys)
pq.add(key);
Java 8 introduced lambda expressions that enabled functional programming in Java. The following code takes each key
(as a variable) in keys
and applies it to pq.add()
:
keys.forEach(key -> pq.add(key));
The syntax of the above code can be simplified as follows (as shown in L7
):
keys.forEach(pq::add);
What are the main differences between object-oriented programming and functional programming?
Test: Robustness
Let us define the testRobustness()
method that calls the auxiliary method testRobustnessAux()
:
@Test
public void testRobustness() {
List<Integer> keys = List.of(4, 1, 3, 2, 5, 6, 8, 3, 4, 7, 5, 9, 7);
Comparator<Integer> natural = Comparator.naturalOrder();
Comparator<Integer> reverse = Comparator.reverseOrder();
testRobustness(new LazyPriorityQueue<>(), keys, reverse);
testRobustness(new EagerPriorityQueue<>(), keys, reverse);
testRobustness(new BinaryHeap<>(), keys, reverse);
testRobustness(new LazyPriorityQueue<>(reverse), keys, natural);
testRobustness(new EagerPriorityQueue<>(reverse), keys, natural);
testRobustness(new BinaryHeap<>(reverse), keys, natural);
}
L7-9
: tests different types of max-PQs. The keys need to be sorted in reverse order for it to test theremove()
method.L11-13
: tests different types of min-PQs. The keys need to be sorted in the natural order for it to test theremove()
method.
The generic types of the PQs in
L4-5
are explicitly coded as<Integer>
, whereas they are simplified to<>
inL7-13
. When do generic types need to be explicitly coded?
Last updated
Was this helpful?