# 2.3. Unit Testing

## Auxiliary Method

Let us create [`PriorityQueueTest`](https://github.com/emory-courses/dsa-java/blob/master/src/test/java/edu/emory/cs/queue/PriorityQueueTest.java) and define `testRobustnessAux()` that checks the robustness of any PQ inheriting `AbstractPriorityQueue`:

{% code lineNumbers="true" %}

```java
/**
 * @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()));
}
```

{% endcode %}

* `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 [`Iterable`](https://docs.oracle.com/en/java/javase/14/docs/api/java.base/java/lang/Iterable.html) has the member method [`forEach()`](https://docs.oracle.com/en/java/javase/14/docs/api/java.base/java/lang/Iterable.html#forEach\(java.util.function.Consumer\)) that takes a [`Consumer`](https://docs.oracle.com/en/java/javase/14/docs/api/java.base/java/util/function/Consumer.html)  and applies each key in the collection to the consumer.
* `L8`: any collection has the member method [`stream()`](https://docs.oracle.com/en/java/javase/14/docs/api/java.base/java/util/Collection.html#stream\(\)) that returns the [`Stream`](https://docs.oracle.com/en/java/javase/14/docs/api/java.base/java/util/stream/Stream.html) of the collection.
  * [`sorted()`](https://docs.oracle.com/en/java/javase/14/docs/api/java.base/java/util/stream/Stream.html#sorted\(java.util.Comparator\)): creates a stream of the collection whose keys are sorted
  * [`collect()`](https://docs.oracle.com/en/java/javase/14/docs/api/java.base/java/util/stream/Stream.html#collect\(java.util.stream.Collector\)): creates a collection specified by the [`Collector`](https://docs.oracle.com/en/java/javase/14/docs/api/java.base/java/util/stream/Collector.html).
  * [`toList()`](https://docs.oracle.com/en/java/javase/14/docs/api/java.base/java/util/stream/Collectors.html#toList\(\)): returns a collector that transforms the stream into a list.
* `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?

## Functional Programming

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

```java
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:

```java
for (T key : keys)
    pq.add(key);
```

Java 8 introduced [lambda expressions](https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html) that enabled functional programming in Java.  The following code takes each `key` (as a variable) in `keys` and applies it to `pq.add()`:

```java
keys.forEach(key -> pq.add(key));
```

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

```java
keys.forEach(pq::add);
```

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

{% hint style="info" %}
Since Java 8, higher-order methods can be defined by parameterizing types of interfaces in the [function](https://docs.oracle.com/en/java/javase/14/docs/api/java.base/java/util/function/package-summary.html) package.
{% endhint %}

## Test: Robustness

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

{% code lineNumbers="true" %}

```java
@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);
}
```

{% endcode %}

* `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?&#x20;

{% hint style="info" %}
The `testRobustness()` method illustrates the benefit of defining `AbstractPriorityQueue` such that any type of PQ can be passed to `testRobustnessAux()` for unit-testing.
{% endhint %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://emory.gitbook.io/dsa-java/priority-queues/unit-testing.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
