简体   繁体   中英

Unit test an edge case with Junit

I have a utility class called StringProcessor . The breakLongWords() method in it, adds zero-width spaces to the input whenever a sequence of characters lack white space for a predefined length:

public class StringProcessor {

    private static final int WORD_MAX_LENGTH = 40;

    public String breakLongWords(CharSequence input) {
        // add a zero-width space character after a word
        // if its length is greater than WORD_MAX_LENGTH and doesn't have any space in it
    }
}

The static field WORD_MAX_LENGTH is an implementation detail and should not be exposed to other classes (including test classes).

Now, how can I test the edge case in JUnit without accessing WORD_MAX_LENGTH ? For example:

@Test
public void breakLongWords_EdgeCase() {
    String brokenText = stringProcessor.breakLongWords
            ("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); // its length should be = WORD_MAX_LENGTH 

    assertEquals(41, brokenText.length()); // 41 (WORD_MAX_LENGTH + 1) is also hard-coded here
}

Usually such fields are made "package-private" (that is with no access modifier) and unit tests are placed on the same package.
So constants are visible for tests and classes from the same package and hidden for others.

You have two choices:

  1. Expose WORD_MAX_LENGTH to your tests.

  2. Maintain a second constant for tests.

I might redesign the StringProcessor and the test.

public class StringProcessor {

    private static final int WORD_MAX_LENGTH = 40;

    public boolean stringLengthIsSafe(CharSequence input){
        if(input.length()>WORD_MAX_LENGTH){
           return false;
        }
        return true;
    }

    public String breakLongWords(CharSequence input) {
        // add a zero-width space character after a word
        // if its length is greater than WORD_MAX_LENGTH and doesn't have any space in it
    }
}

And then test on the boolean.

@Test
public void breakLongWords_EdgeCase() {
    boolean safeString = stringProcessor.stringLengthIsSafe
            ("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); // its length should be = WORD_MAX_LENGTH 

    assertEquals(true, safeString); // 41 (WORD_MAX_LENGTH + 1) is also hard-coded here
}

In your final implementation, breakLongWords could implement stringLengthIsSafe before attempting any manipulation of the CharSequence.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM