I have a method which is a part of the interface I am implementing. This method calls another private method which uses a random number generator to produce output and returns it to the calling method. I want to test the calling method. How can I do that? This is the method under test:
@Override
public String generate(int wordCount) {
StringBuilder sentence = new StringBuilder();
List<String> selectedStrings = selectRandomStringsFromInternalVocabulary(wordCount, new Random());
selectedStrings.sort(Comparator.<String>naturalOrder());
swapOddIndexedStringsWithEvenIndexedStrings(selectedStrings);
for (String word: selectedStrings)
sentence.append(word)
.append(" ");
return sentence.toString().trim();
}
This is the method that uses random number generator:
private List<String> selectRandomStringsFromInternalVocabulary(int wordCount, Random random) {
List<String> selectedStrings = new ArrayList<>();
int wordCountInVocabulary = internalVocabulary.size();
while (wordCount-- != 0) {
int stringIndex = random.nextInt(wordCountInVocabulary);
selectedStrings.add(internalVocabulary.get(stringIndex));
}
return selectedStrings;
}
There are a few things that I've thought I can do: 1. Make the second method package-private and test it. But I don't want to test a private method if I can avoid it. 2. Add Random as a parameter to the calling function and pass a mock during test. However, its part of the interface and other classes implementing it does not use RNG. Furthermore, I don't want clients to know about the implementation details.
I have gone through these questions: 1. Unit testing methods with indeterminate output 2. Unit Testing a function with random behavior
But the suggestions are similar to what I mentioned above.