一对夫妇的,使这段代码难以测试的问题是:
- 你的功能洗牌声明为static
- 的函数调用Collections.shuffle,使得它真的很难嘲笑
这里有一些建议,你如何可以测试这种方法,尽管他们需要一些改变你的设计:
public class WordUtil {
public void shuffle(String word) {
// Store string into array
// -> It is better to code to the interface, eg, List, Set, Map
// than to the implementation, eg. ArrayList, LinkedList, HashMap, etc.
List<Character> wordShuffled = new ArrayList<Character>();
// loop the index of the string
for (int i = 0; i < wordE.length(); i++) {
wordShuffled.add(word.charAt(i));// add the word
}
Collections.shuffle(wordShuffled);// shuffle the word
}
// we are making this method visible only for testing purposes but
// shouldn't be regarded as public API
void shuffle(Collection c) {
Collections.shuffle(c);
}
}
public class WordUtilTest {
private boolean shuffleForCollectionWasCalled;
private Collection collectionForShuffle;
public void testShuffle() throws Exception {
WordUtil util = new WordUtil_ForTest();
String word = "some word";
util.shuffle(word);
assertTrue(shuffleForCollectionWasCalled);
List<Character> expected = new ArrayList<Character>();
for (int i = 0; i < word.length; i++) {
expected.add(word.charAt(i);
}
assertEquals(expected, collectionForShuffle);
}
private static class WordUtil_ForTest extends WordUtil {
@Override
void shuffle(Collection c) {
shuffleForCollectionWasCalled = true;
collectionForShuffle = c;
}
}
}
虽然这似乎有点令人费解,我们需要引入void shuffle(Collection c)
,因为它使我们能够控制的Collections.shuffle
使其确定性的行为,我们在WordUtil_ForTest
实现很简单,因为我们没有测试Collections.shuffle
如何完成其工作(这应该在JDK中得到很好的测试),我们只关心我们发送正确的参数给它。
可以通过添加条件处理空输入和另一个边缘延伸的情况下该测试。
@CarlosZ提出了一个有效的观点。为什么测试Collections.shuffle(),因为我们知道它工作正常。在那种情况下,为什么测试这个功能呢?for循环也可以用标准API来替换,以将原始字符串转换为字符列表,从而将您的代码减少到一两行。 – Rahul 2011-03-26 04:20:57