Answered step by step
Verified Expert Solution
Link Copied!

Question

1 Approved Answer

Modify the Person class from the Java Tutorial so that it is immutable, and create a JUnit test class for it called PersonTest.java. Both classes

Modify the Person class from the Java Tutorial so that it is immutable, and create a JUnit test class for it called PersonTest.java. Both classes should reside in the package "person". Your code should pass all of your unit tests, which should cover all statements and conditions in your code, and your code should pass all of the tests in Web-CAT. Your source code (but not the tests) should also meet all the Web-CAT style guidelines. You may submit your code to Web-CAT as many times as you like before the deadline.

Walkthrough of the Entire Homework

Dr. K provides a walkthrough of the entire mini-project in his videos:

A Tour of the Person Class from the Java Tutorial (1 video)

Making the Person Class Immutable (6 videos)

Unit Testing the Immutable Person Class (5 videos)

Note that Web-CAT style guidelines have been ignored in these videos. You will have to fix the style problems in your submission, including adding Javadocs to the Person class. You can do this as you follow along with the video or any time after.

Important Epilogue to the Videos

After following along in all the videos, your Person class will still have a few minor structural issues that will need to be resolved in order to pass all the Web-CAT tests:

In the areAnyNull() and areAnyInvalid() helper methods generated by Eclipse, the parameter names chosen by Eclipse are exactly the same as the names of the instance fields, which is considered a bad practice (and rejected by Web-CAT). There are two ways to fix this, with the second option being much easier than the first: Option 1 - You can refactor the parameter names to be different (such as renaming "name" to "nameX"). To do this, place the cursor within the "name" parameter of the areAnyNull() method signature, type Alt-Shift-R, and change the name of the parameter. This should change all instances (even in your Javadocs, if you've added them already) for that method. Repeat this action for each of the other parameter names within the areAnyNull() method signature, and again for all parameter names within the areAnyInvalid() method signature. Option 2 - You can reintegrate the methods you extracted during the video, placing the code back into the constructor. To do this, place the cursor within the call to areAnyNull() within the constructor, and type Alt-Shift-I (that's the letter "i") to "inline" the method and click OK. Repeat this action for the call to the areAnyInvalid() method.

The Person constructor throws NullPointerException if any parameter is null, but Web-CAT considers it a bad practice to explicitly throw this exception. It can indeed be confusing in some instances, but it's certainly not a bad practice in general. However, we need to pass the Web-CAT tests, so you must change the constructor to throw a new IllegalArgumentException instead. As a result, you will also need to update the "expect=" annotation for several of your test methods accordingly, from NullPointerException.class to IllegalArgumentException.class.

Finally, within the equals() method generated by Eclipse, the last if() statement is actually redundant, and Web-CAT will reject it as such. The code is perfectly acceptable as it is, and arguably more readable. However, we again must appease Web-CAT. To do so, you'll need to change the following two lines: if (!emailAddress.equals(other.emailAddress)) { return false; } return true into this one line instead: return emailAddress.equals(other.emailAddress); The code is now technically less redundant, but most developers would probably prefer the original form as more readable.

After making these changes, your code should still pass all the test methods in PersonTest, and you should still have 100% code coverage from EclEmma. Once you've addressed all the style issues as well, your project should receive 20/20 from Web-CAT.

PersonTest.java

package person;

import static org.junit.Assert.*; import java.io.ByteArrayOutputStream; import java.io.PrintStream; import java.time.chrono.IsoChronology; import org.junit.Before; import org.junit.Test;

@SuppressWarnings("javadoc") public class PersonTest {

private final ByteArrayOutputStream outContent = new ByteArrayOutputStream();

private Person fred; private Person jane;

@Before public void setUp() throws Exception { System.setOut(new PrintStream(outContent)); fred = new Person( "Fred", IsoChronology.INSTANCE.date(1980, 6, 20), Person.Sex.MALE, "fred@example.com"); jane = new Person( "Jane", IsoChronology.INSTANCE.date(1990, 7, 15), Person.Sex.FEMALE, "jane@example.com"); }

@Test public void testGetName() { assertEquals("Fred", fred.getName()); assertEquals("Jane", jane.getName()); }

@Test public void testGetBirthday() { assertEquals(IsoChronology.INSTANCE.date(1980, 6, 20), fred.getBirthday()); assertEquals(IsoChronology.INSTANCE.date(1990, 7, 15), jane.getBirthday()); }

@Test public void testGetGender() { assertEquals(Person.Sex.MALE, fred.getGender()); assertEquals(Person.Sex.FEMALE, jane.getGender()); }

@Test public void testGetEmail() { assertEquals("fred@example.com", fred.getEmailAddress()); assertEquals("jane@example.com", jane.getEmailAddress()); }

@Test public void testGetAge() { assertTrue(fred.getAge() >= 35); assertTrue(jane.getAge() >= 25); }

@Test public void testEnumSex() { assertEquals(Person.Sex.MALE, Person.Sex.valueOf("MALE")); assertEquals(2, Person.Sex.values().length); }

}

Person.java

import java.util.List; import java.util.ArrayList; import java.time.chrono.IsoChronology; import java.time.LocalDate; import java.time.temporal.ChronoUnit; import java.time.Period; public class Person { public enum Sex { MALE, FEMALE } String name; LocalDate birthday; Sex gender; String emailAddress; Person(String nameArg, LocalDate birthdayArg, Sex genderArg, String emailArg) { name = nameArg; birthday = birthdayArg; gender = genderArg; emailAddress = emailArg; } public int getAge() { return birthday .until(IsoChronology.INSTANCE.dateNow()) .getYears(); } public void printPerson() { System.out.println(name + ", " + this.getAge()); } public Sex getGender() { return gender; } public String getName() { return name; } public String getEmailAddress() { return emailAddress; } public LocalDate getBirthday() { return birthday; } public static int compareByAge(Person a, Person b) { return a.birthday.compareTo(b.birthday); } public static List createRoster() { List roster = new ArrayList<>(); roster.add( new Person( "Fred", IsoChronology.INSTANCE.date(1980, 6, 20), Person.Sex.MALE, "fred@example.com")); roster.add( new Person( "Jane", IsoChronology.INSTANCE.date(1990, 7, 15), Person.Sex.FEMALE, "jane@example.com")); roster.add( new Person( "George", IsoChronology.INSTANCE.date(1991, 8, 13), Person.Sex.MALE, "george@example.com")); roster.add( new Person( "Bob", IsoChronology.INSTANCE.date(2000, 9, 12), Person.Sex.MALE, "bob@example.com")); return roster; } }

Step by Step Solution

There are 3 Steps involved in it

Step: 1

blur-text-image

Get Instant Access to Expert-Tailored Solutions

See step-by-step solutions with expert insights and AI powered tools for academic success

Step: 2

blur-text-image

Step: 3

blur-text-image

Ace Your Homework with AI

Get the answers you need in no time with our AI-driven, step-by-step assistance

Get Started

Recommended Textbook for

Students also viewed these Databases questions

Question

=+How should it be delivered?

Answered: 1 week ago