arrow-left

All pages
gitbookPowered by GitBook
1 of 1

Loading...

2.3. Unit Testing

Robustness tests.

hashtag
Auxiliary Method

Let us create PriorityQueueTestarrow-up-right and define testRobustnessAux() that checks the robustness of any PQ inheriting AbstractPriorityQueue:

  • L6: the generic type T is defined specifically for this method such that the priority queue pq, the list keys, and the comparator comp take the same type T that is comparable.

  • L7: any collection that inherits the interface has the member method that takes a and applies each key in the collection to the consumer.

  • L8: any collection has the member method that returns the of the collection.

    • : creates a stream of the collection whose keys are sorted

    • : creates a collection specified by the

  • L9: iterates each of the sorted keys and compares it to the returned value of pq.remove().

What are the advantages of defining a method-level generic type?

hashtag
Functional Programming

The following code shows a traditional way of iterating over a list (that is equivalent to L7 above):

Java 5 introduced an enhanced for loop that simplified the traditional for loop:

Java 8 introduced that enabled functional programming in Java. The following code takes each key (as a variable) in keys and applies it to pq.add():

The syntax of the above code can be simplified as follows (as shown in L7):

What are the main differences between object-oriented programming and functional programming?

circle-info

Since Java 8, higher-order methods can be defined by parameterizing types of interfaces in the package.

hashtag
Test: Robustness

Let us define the testRobustness() method that calls the auxiliary method testRobustnessAux():

  • L7-9: tests different types of max-PQs. The keys need to be sorted in reverse order for it to test the remove() method.

  • L11-13: tests different types of min-PQs. The keys need to be sorted in the natural order for it to test the remove() method.

The generic types of the PQs in L4-5 are explicitly coded as <Integer>, whereas they are simplified to <> in L7-13. When do generic types need to be explicitly coded?

circle-info

The testRobustness() method illustrates the benefit of defining AbstractPriorityQueue such that any type of PQ can be passed to testRobustnessAux() for unit-testing.

/**
 * @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()));
}
.
  • : returns a collector that transforms the stream into a list.

  • Iterablearrow-up-right
    forEach()arrow-up-right
    Consumerarrow-up-right
    stream()arrow-up-right
    Streamarrow-up-right
    sorted()arrow-up-right
    collect()arrow-up-right
    lambda expressionsarrow-up-right
    functionarrow-up-right
    for (int i=0; i<keys.size(); i++)
        pq.add(keys.get(i));
    for (T key : keys)
        pq.add(key);
    keys.forEach(key -> pq.add(key));
    keys.forEach(pq::add);
    @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);
    }
    Collectorarrow-up-right
    toList()arrow-up-right