Catching an Unexpected Error

In this section, we'll see how continuous testing can come in handy at unexpected times, and learn a clever debugging trick that it enables.

It's finally time to fix the test failure that we introduced several sections ago. The problem, as you'll remember, was that getTopN could not handle unsorted lists. We'll fix this problem by creating a sorted copy of the input list, and then using that to grab the top N elements. Let's redefine TopTen.java like this:

  import java.util.ArrayList;
  import java.util.Collections;
  import java.util.List;

  public class TopTen {
    public static List getTopN(int i, List list) {
      List sorted = new ArrayList(list);
      Collections.sort(sorted);
      List returnThis = new ArrayList();
      for (int j = 0; j < i; j++) {
        returnThis.add(sorted.get(j));
      }
      return returnThis;
    }
  }

You'll see that testTopThreeIntsUnsorted now passes, but testTopJoke fails. Why? Right-click the marker in the Problems view and select View Trace. You'll see that a ClassCastException is thrown in Arrays.mergeSort(). If you are an experienced Java programmer, you may realize that this is likely because some element type in a sorted collection does not implement Comparable. This is the kind of error that can sometimes take you by surprise. Continuous testing catches it quickly, and notifies you so you can deal with it before you move on.

But which element type is the culprit? In this case, it's not hard to figure it out, but in more complicated real-life scenarios, it might be difficult to figure out the behavior of the callers of the sort method. You could imagine examining the source, or firing up a debugger, but Continuous Testing allows a third useful option. Simply insert a debugging print statement in the getTopN method to see what element types are being sorted over:

  public static List getTopN(int i, List list) {
    System.out.println("getTopN element class: " + list.get(0).getClass());
    ...
  }
As soon as you save, your tests will be re-run, and the console will pop up with the answer to your question. (You may have disabled (under Window > Preferences > Run/Debug > Console) the console's habit of popping to the front on output, in which case you will have to manually bring the Console view to the front.) The element types in question are Integer, String, and Joke. A moment's reflection shows that we will need to have Joke implement Comparable (Doing this correctly is left as an exercise for the reader, but don't do it yet. We need the failure to stay as we work through the rest of the tutorial.)