-3

I'm making a JUnit test that takes in a Person and checks if a PersonException (my custom exception) is returned. PersonException extends Exception and Person has a method SetDOB() that throws a PersonException if the individual is over 100. So far, the exception prints in the console, as it should, but for some reason still fails the test. Here's the relevant code.

//JUnit Test
@Test(expected = PersonException.class)
public void testBadShieffer1() {
    Staff wrongShieffer = new Staff("Bob", "Lloyd", "Shnieffer",
        new Date(1737, 2, 25), "Shieffer Lane", "21277777778" /*PhoneNumber*/ ,
        "RadioMan@shieffer.shief",
        "Radio time.", 10, 500000.00, new Date(1991 + 1900, 1, 1), eTitle.MR);
    //This constructor calls SetDOB()
    fail("No PersonExceptions were thrown.");
}

//setDOB
public void setDOB(Date DOB) {
    try {
        if (((new Date()).getYear() + 1900) > DOB.getYear() + 100)
            throw new PersonException(this);
        else
            this.DOB = DOB;
    } catch (PersonException p) {
        System.out.println(p + " is over 100 years old!");
    }
}

//PersonException class
public class PersonException extends Exception {
    private Person p;

    public PersonException() {
        super();
    }

    public PersonException(String message) {
        super(message);
    }

    public PersonException(Person p) {
        super(p.getLastName());
        this.p = p;
    }

    public Person P() {
        return p;
    }
}

I apologize if this is a tad lengthy, but I believe everything that needs to be in there is present. Thanks in advance for any help!

CollinD
  • 7,304
  • 2
  • 22
  • 45
JonRicardo
  • 15
  • 5
  • A word of advice, use the extremely cool and good Java 8 time api (https://docs.oracle.com/javase/8/docs/api/java/time/package-summary.html) instead of the very bad and lame old Date api (http://stackoverflow.com/questions/1969442/whats-wrong-with-java-date-time-api). – ThisIsNoZaku Mar 19 '17 at 02:39
  • 4
    The way it's written, it looks like `setDOB` will never throw a `PersonException`, because right after it's thrown, you're catching it within the `setDOB` method. A test with `(expected = PersonException.class)` will never pass if you end up catching the exception. – Thomas Mar 19 '17 at 02:40
  • Thomas, thanks for the reply. That was actually my guess as well. Although, I'm not sure how to go about throwing an Exception in a try statement without having catch it. Any suggestions? – JonRicardo Mar 19 '17 at 02:57
  • Sorry, you do that by **studying** the concept of exceptions. It is not enough to hear about some concept, and then putting that into your code. You are like a person that is driving a car that has learned how to accelerate; and that assumes "maybe i will figure how to slow down later on". What I mean is: dont do trial and error. **Study** and learn; for example from here: https://docs.oracle.com/javase/tutorial/essential/exceptions/index.html – GhostCat Mar 19 '17 at 19:25

1 Answers1

2

As stated in my comment, the test case will never pass because the exception being thrown is also being caught in the same method (which doesn't make much sense). You can fix this one of two ways, and it depends what kind of exception you want to throw. A Checked Exception will need to be caught and handled wherever setDOB() is called. You can implement this by changing setDOB to:

public void setDOB(Date DOB) throws PersonException {

    if (((new Date()).getYear() + 1900) > DOB.getYear() + 100) {
            throw new PersonException(this);
    }
    else {
        this.DOB = DOB;
    }
}

The other way you could fix this is by making PersonException an Unchecked Exception. This type of exception doesn't need to be caught at the call sight. You could achieve this by changing setDOB() to:

 public void setDOB(Date DOB) {

    if (((new Date()).getYear() + 1900) > DOB.getYear() + 100) {
            throw new PersonException(this);
    }
    else {
        this.DOB = DOB;
    }
}

And then have PersonException extend RuntimeException, rather than Exception, like so:

public class PersonException extends RuntimeException

For your unit test to pass as is, the Unchecked approach would work. You can learn more about exceptions here.

Thomas
  • 1,123
  • 3
  • 13
  • 36
  • I decided to go with the Checked approach. I was reluctant at first, because I would need to add throws PersonException to several several methods as a result, but it seems like the more logical way to do things in this situation. Thank you for being so informative and quick to respond! – JonRicardo Mar 19 '17 at 22:22