Search code examples
javaunit-testingjunittest-suite

How to test a constructor in a proper way for JUnit?


I am currently writing a Junit testing suite for certain codes.

What I am doing is, there is a class called Person, in which its constructor has variables of name, height, and weight.

In its constructor, it throws an exception if the number of characters for the name is longer than 20.

If the test needs to test that the constructor does not accept names longer than 20 characters, how should I write a test method?

For example, if I write:

@Test (expected = IllegalArgumentException.class)
public void testPersoin() {
Person person = new Person("BobBobBobBobBobBobBobBobBobBobBobBobBobBobBobBobBobBob", "172", "62");
}

and when I run it, it would pass the test case, but it is only testing the length of the name: "BobBobBobBobBobBobBobBobBobBobBobBobBobBobBobBobBobBob", but not any longer or shorter names.

Is there any proper way that tests whether the character of names is longer than 20 or not? Should I write if/else condition in a test method? How should I demonstrate the boundaries of if in a test suite?

Thanks!


Solution

  • I am not sure what you need but maybe this is what you are after:

    @Test (expected = IllegalArgumentException.class)
    public void testPersoin() {
        // Extract the name
        String name = "BobBobBobBobBobBobBobBobBobBobBobBobBobBobBobBobBobBob";
        // Assert that it is over 20 characters long
        assertTrue(name.length() > 20);
        person = new Person(name, "172", "62");
    }
    

    Sometimes you might need to assert also that test parameters are valid before testing. But it is not the best approach. Better is just to to make the test as clear as possible, handle all the cases and name the cases properly, like:

    private static final String NAME_10 = "0123456789"; // below 20
    private static final String NAME_20 = NAME_10 + NAME_10; // exactly 20
    private static final String NAME_21 = NAME_20 + "x"; // over 20
    
    private Person person;
    
    @Test(expected = IllegalArgumentException.class)
    public void personNameOver20Throws() {
        new Person(NAME_21, "172", "62");
    }
    
    // I assume that null and empty names are not allowed either
    @Test(expected = IllegalArgumentException.class)
    public void personNameNullThrows() {
        new Person(null, "172", "62");
    }
    
    @Test(expected = IllegalArgumentException.class)
    public void personNameEmptyThrows() {
        person = new Person("", "172", "62");
    }
    
    @Test
    public void personNameBelow20Works() {
        person = new Person(NAME_10, "172", "62");
    }
    
    @Test
    public void personNameExactly20Works() {
        person = new Person(NAME_10, "172", "62");
    }