Writing the BubbleSortTest class

The test classes are separated from the production classes. They go into the src/test/java directory. When we have a class named, for example, BubbleSort, then the test will be named BubbleSortTest. This convention helps the executing environment to separate the tests from those classes that do not contain tests but are needed to execute the tests. To test the sort implementation we have just created, we can furnish a class that contains, for now, a single canSortStrings method.

Unit test method names are used to document the functionality being tested. As the JUnit framework invokes each and every method that has the @Test annotation, the name of the test is not referenced anywhere in our code. We can bravely use arbitrary long method names; it will not hinder readability at the place where the method is invoked.

package packt.java9.by.example.ch03.bubble; 

// imports deleted from print

public class BubbleSortTest {

@Test
public void canSortStrings() {
ArrayList actualNames = new ArrayList(Arrays.asList(
"Johnson", "Wilson",
"Wilkinson", "Abraham", "Dagobert"
));

The method contains ArrayList with the actual names that we have already gotten familiar with. As we have a sort implementation and interface that needs SortableCollection, we will create one backed up by ArrayList.

        SortableCollection namesCollection = new SortableCollection() { 

@Override
public Object get(int i) {
return actualNames.get(i);
}

@Override
public int size() {
return actualNames.size();
}
};

We declared a new object that has the SortableCollection type, which is an interface. To instantiate something that implements SortableCollection, we will need a class. We cannot instantiate an interface. In this case, define the class in the place of the instantiation. This is called an anonymous class in Java. The name comes from the fact that the name of the new class is not defined in the source code. The Java compiler will automatically create a name for the new class, but that is not interesting for the programmers. We will simply write new SortableCollection() and provide the needed implementation immediately following between { and }. It is very convenient to define this anonymous class inside the method as, this way, it can access ArrayList without passing a reference to ArrayList in the class.

As a matter of fact, the reference is needed, but the Java compiler automatically does this. The Java compiler, in this case, also takes care that automatic reference passing this way can only be done using variables that were initialized and will not change during the execution of the code after the instantiation of the anonymous class. The variable actualNames was set and it should not be changed in the method later. As a matter of fact, we can even define actualNames to be final and this would have been a requirement if we used Java 1.7 or earlier. Starting with 1.8, the requirement is that the variable is effectively final, but you need not declare it to be final.

The next thing that we need is a Swapper implementation for ArrayList. In this case, we will define a whole class inside the method. It can also be an anonymous class, but this time I decided to use a named class to demonstrate that a class can be defined inside a method. Usually, we do not do that in production projects.

        class SwapActualNamesArrayElements implements Swapper { 
@Override
public void swap(int i, int j) {
final Object tmp = actualNames.get(i);
actualNames.set(i,actualNames.get(j));
actualNames.set(j, tmp);

}
}

Last, but not least, we will need a comparator before we can invoke the sort. As we have Strings to compare, this is easy and straightforward.

        Comparator stringCompare = new Comparator() { 
@Override
public int compare(Object first, Object second) {
final String f = (String) first;
final String s = (String) second;
return f.compareTo(s);
}
};

Having everything prepared for the sorting, we will finally need an instance of the Sort implementation, set the comparator and the swapper, and invoke the sort.

        Sort sort = new BubbleSort(); 
sort.setComparator(stringCompare);
sort.setSwapper(new SwapActualNamesArrayElements());
sort.sort(namesCollection);

The last, but most important part of the test is to assert that the result is the one that we expect. JUnit helps us do that with the aid of the Assert class.

        Assert.assertEquals(Arrays.asList("Abraham", "Dagobert", "Johnson", "Wilkinson", "Wilson"), actualNames); 
}

}

The call to assertEquals checks that the first argument, the expected result, equals the second argument, the sorted actualNames. If they differ, then AssertionError is thrown; otherwise, the test just finishes fine.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.222.182.66