CSIS 3103 - Lab 1: Java classes and unit testing
Sept. 15, 2010


Objectives

This assignment involves creating a Java project in Eclipse, and defining classes to represent time values. We will use a technique called test driven development to implement the time class. This involves implementing small code segments and frequently testing the results using unit testing (a group of test methods that target specific features of a class's behavior). We'll also improve existing code by using a technique called refactoring.

You can work in pairs on this assignment.

Do as much as you can in class, and if you don't finish, continue working on this as a homework assignment.

The Time Class

A Time object contains values for hours, minutes, and seconds using military time (hours is a value in 0 to 23). The operations include getters for each field, methods that increment each of the fields, a method for comparing two Time objects for equality and a method that gives the string representation of the time.

What to do

a. Declare the hours field as follows:

private int hours;

Similarly, declare the minutes and seconds fields.

b. Have Eclipse generate the constructors as described below by using Source -> Generate Constructors Using Fields... (have it also generate comments)

c. Have Eclipse generate getter methods for each of the fields by right-clicking in the editor window and selecting Source -> Generate Setters and Getters... (also generate comments). Do not generate setter methods for this class. Add appropriate explanatory information to the comments.

d. Have Eclipse generate a toString method with Source -> Generate toString()... Note that the generated method uses a predefined format for the fields. Modify this to display the time in the form hrs:mins:secs (put colon characters between each time component).

e. Write an incrementSeconds method to simply add 1 to the seconds field. Note that just adding 1 is not going to be correct in all cases, but leave it like that for now. We'll fix this later. Write similar methods for incrementMinutes and incrementHours.

Testing the Time Class

Its time to check our work to see how were doing so far. The usual way to do this is with a JUnit test class. We'll learn more about unit testing later, but for this assignment, start by making a JUnit Test Case class - expand the new class option on the toolbar and select:      Call it TimeTest

Delete everything in the editor window and replace it with this prewritten class: TimeTest.java.

Now run TimeTest as a JUnit Test. You will see a test view displayed with a report of which tests worked and which failed (the method name will be marked an X). Click on one of the failed tests to see an explanation of the problem in the bottom panel. Double click a failed test to select the test method in the source code. See if you can determine what is wrong by looking at the Time object and the operation performed to see what the expected result should have been.

Now fix the errors, one at a time:

a. A problem occurs in incrementSeconds when 59 seconds is incremented and the seconds value reached 60 it should roll over to 0. Change incrementSeconds to do this. Save your changes and run the test again by clicking in the JUnit view. Did this fix the problem? Did it create any new problems? What else should have occurred when seconds reached 60? Fix this, save the changes and run the test again. More tests should work now, but other problems still exist. Go on to fix the incrementMinutes method. Test to be sure this is working properly before fixing the incrementHours method.

b. Look at your incrementSeconds method. You probably have an if statement that checks to see whether minutes has reached 60 and makes some adjustments. Select this entire if statement and choose Refactor -> Extract Method... Give the extracted method the name fixMinutes and complete the wizard. Next find the if statement that does a similar check and adjustment to the hours field. Repeat the above steps to refactor this code and make a fixHours helper method. This refactoring process is used to improve the style of working code (without breaking it). Its not perfect, and you might see other ways to improve the code with manual changes. 

c. Everything should be working now except the equals method (and maybe toString()). The problem is that the equals method from the Object class is being used and it doesn't know about hours, minutes, and seconds. You can try writing your own equals method to override the default one or have Eclipse write it for you with Source -> Generate hashCode() and equals()... We don't actually need the hashCode() method so ignore it. The tests should now succeed with the generated equals method.

If the test for toString() fails, make the necessary changes.

You should now see a Green Bar at the top of the test view indicating that your Time class passed all tests. Congratulations!

Note that the current time should be printed in the console panel after each test - see the last statement in testToString.

Check your Javadocs

Click on the class name and the method names of all the elements in your Time class. You should see the comments you wrote formatted as Javadocs.

Take your work with you

If you created a workspace on your removable media, you already have all of your files. Otherwise, you should copy your source files to work on them outside of the lab. One way to do this within Eclipse is to use the File -> Export -> General -> File System... command. Another is to just copy the project folder directly from C:\temp. Then on your computer use File -> Import -> General -> Existing Projects into Workspace to load the project. Note that for an existing project, all you really need is the src folder. Just drag-n-drop the Java files into the corresponding src folder.