How to refactor a method to make it easier to test
下面是一个方法,我很难弄清楚如何使用JUnit进行测试。
这种方法很难测试,因为它取决于其他方法的结果(例如getClosestDcoumentCode)。
基于我对JUnit的阅读,这表明我应该重构该方法。 但是怎么样? 如果不需要重构,您如何测试依赖于其他方法的方法?
谢谢,
埃利奥特
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | private static String findPrincipal(List<DocumentKey> documentkeys_) { Hashtable<String, Integer> codecounts = new Hashtable<String, Integer>(); for (DocumentKey document : documentkeys_) { int x = 0; String closestCode = getClosestDocumentCode(document.candidates); if (closestCode == null) continue; int thecount = 0; if (codecounts.containsKey(closestCode)) thecount = codecounts.get(closestCode); if (document.hasKey) thecount += 2; else thecount++; codecounts.put(closestCode, new Integer(thecount)); x++; } String closestCode = getClosestCode(codecounts); return closestCode; } |
好吧,首先,我想知道该方法是否真的需要是静态的,以及该类正在做什么。看起来它可能是一个GOD类,或者至少它违反了单一责任原则。 getClosestCode有什么作用?如果它是一个类,你可以在测试中将它与一个存根注入到测试类中。
EasyMock会让你模拟方法响应,但我不确定你如何模拟静态方法。
一般来说,你可能需要
听起来像
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | public class PrincipalFinderImpl implements PrincipalFinder { private CodeFinder codeFinder; public PrincipalFinderImpl(CodeFinder codeFinder) { this.codeFinder = codeFinder; } public String findPrincipal(List<DocumentKey> documentkeys_) { Hashtable<String, Integer> codecounts = new Hashtable<String, Integer>(); for (DocumentKey document : documentkeys_) { int x = 0; String closestCode = codeFinder.getClosestDocumentCode(document.candidates); if (closestCode == null) continue; int thecount = 0; if (codecounts.containsKey(closestCode)) thecount = codecounts.get(closestCode); if (document.hasKey) thecount += 2; else thecount++; codecounts.put(closestCode, new Integer(thecount)); x++; } String closestCode = codeFinder.getClosestCode(codecounts); return closestCode; } } |
现在,应该很容易创建另一个实现
我没有深入阅读这个方法。但是如果私有方法需要测试,则表明您的设计存在问题。至少Kent Beck这么认为。
关于JUnit Second Edition的存根调用有一章,如果您认为现有代码没有写入测试驱动开发标准,我建议您查看一下。