Lab 6: JUnit Testing
Overview
Having thorough tests can ensure the behavior of a class matches its
specification, but writing thorough tests can be challenging. In this
assignment you will gain experience writing unit tests for an AutoCompleter
interface and use it to test your own implementation of the interface.
Assignment
AutoCompleter interface
The AutoCompleter interface has the following methods:
boolean add(String word)— returnstrueifwordis added to the object (a word should not be added if it is already in the auto completer). Ifwordisnullor an empty string, anIllegalArgumentExceptionis thrown.int size()— returns the number of items in the auto completer.boolean exactMatch(String target)— returnstrueiftargetis found in the auto completer. Iftargetisnullor an empty string, the method returnsfalse.String[] allMatches(String prefix)— returns an array of all the strings in the object that begin with theprefix. Ifprefixis an empty string, an array of all the strings in the auto completer are returned. Ifprefixisnull, an empty array is returned.String getBackingClass()— returns aStringindicating the fully qualified name of the data structure used to store the words for the AutoCompleter. E.g.,"java.util.ArrayList".static String format(long nanoseconds)— returns a human-friendly string representing the number ofnanoseconds. The format of the string must be consistent with the examples and rules below. Note: this method is declaredstaticwhich means that it should be implemented in the interface. If a negative value is supplied, the method should throw anIllegalArgumentException.
All words stored by an AutoCompleter implementation for this assignment should be converted to lowercase. As a result, duplicate detection, exact matching, and prefix matching are case-insensitive. For example, "Dog", "DOG", and "dog" represent the same stored word, and a prefix of "Al" should match a stored word such as "alpha".
The format() method should select the largest time unit for which the first displayed value is at least 1. Use the following output forms:
| Nanosecond value | Output format |
|---|---|
| less than 1 microsecond | whole nanoseconds |
| less than 1 millisecond | microseconds to one decimal place |
| less than 1 second | milliseconds to one decimal place |
| less than 1 minute | seconds to one decimal place |
| less than 1 hour | whole minutes and seconds to one decimal place |
| less than 1 day | whole hours, whole minutes, and whole seconds |
| 1 day or more | whole days, whole hours, and whole minutes |
Examples include:
- 2 days 5 hours 32 minutes
- 14 hours 1 minute 8 seconds
- 42 minutes 55.3 seconds
- 18.8 seconds
- 998.8 milliseconds
- 318.8 microseconds
- 7 nanoseconds
- 0 nanoseconds
Values should remain in the unit selected by the original nanosecond value, even if rounding causes the displayed value to reach the next unit. For example, 999_999 nanoseconds should be displayed as 1000.0 microseconds, not 1.0 millisecond.
You must implement the static format() method and write complete javadocs for all the methods in AutoCompleter.
Unordered List Implementation
You must create a class, UnorderedList, that implements the AutoCompleter
interface using an unordered list. Your class must have only one private
attribute: private final List<String> items that is assigned via a
one-argument constructor.
The constructor must:
- throw an
IllegalArgumentExceptionif the suppliedListisnull, - use the supplied
Listobject as the backing data structure rather than creating a different list, - convert the supplied words to lowercase,
- remove duplicate words while preserving the order of their first occurrence.
You may assume that the List passed to the constructor is modifiable and does not contain null elements.
distinct() stream method. If you
have a list called items you can do the following to remove duplicates:
List<String> unique = items.stream().distinct().toList();
items.clear();
items.addAll(unique);
Remember that for this assignment the stored words should be lowercase before duplicates are removed.
Testing
You must create JUnit tests for all of the methods in the AutoCompleter
interface. These tests should be rigorous and ensure all methods behave as
specified in the requirements. If the behavior of specific methods is not
completely specified, please ask your instructor for clarification.
Your tests should consider normal cases, boundary cases, invalid input, and behavior that may change as data is added to the auto completer. A test suite that demonstrates only that a correct implementation works is not necessarily thorough; your tests should also be capable of distinguishing correct behavior from plausible incorrect implementations.
Use the tests to ensure your UnorderedList implementation conforms to the requirements.
Your instructor may verify your tests by providing multiple faulty implementations to see if your tests catch the errors embedded in the faulty implementations.
Acknowledgement
This laboratory assignment, developed by Dr. Chris Taylor.