Java 如何重构方法以使其更易于测试
下面是一个我很难弄清楚如何使用JUnit进行测试的方法。Java 如何重构方法以使其更易于测试,java,testing,refactoring,junit,Java,Testing,Refactoring,Junit,下面是一个我很难弄清楚如何使用JUnit进行测试的方法。 此方法很难测试,因为它依赖于其他方法的结果(例如GetCloseStdCumentCode) 根据我对JUnit的阅读,这建议我应该重构该方法。但是怎么做呢?如果不需要重构,那么如何测试依赖于其他方法的方法 谢谢, 艾略特 private static String findPrincipal(List<DocumentKey> documentkeys_) { Hashtable<String, Integer
此方法很难测试,因为它依赖于其他方法的结果(例如GetCloseStdCumentCode) 根据我对JUnit的阅读,这建议我应该重构该方法。但是怎么做呢?如果不需要重构,那么如何测试依赖于其他方法的方法 谢谢, 艾略特
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;
}
私有静态字符串findPrincipal(列出文档键){
Hashtable codecounts=新的Hashtable();
用于(文档密钥文档:文档密钥){
int x=0;
字符串closestCode=getClosestDocumentCode(document.candidates);
如果(closestCode==null)继续;
整数=0;
if(codeconts.containsKey(closestCode))
count=codeconts.get(closestCode);
if(document.hasKey)
计数+=2;
其他的
count++;
put(closestCode,新整数(thecount));
x++;
}
字符串closestCode=getClosestCode(codeconts);
返回关闭代码;
}
上有一章是关于存根调用的,如果您认为您现有的代码不是按照测试驱动开发标准编写的,我建议您看看这个章节。首先,我想知道该方法是否真的需要是静态的,以及该类在做什么。看起来它可能是一个神类,或者至少它违反了单一责任原则。getClosestCode做什么?如果它是一个类,您可以在测试中将它与存根一起注入测试类
EasyMock将允许您模拟方法响应,但我不确定您如何模拟静态方法
一般来说,您可能需要
我觉得
getClosestCode
和getClosestDocumentCode
与findPrincipal
方法属于不同的职责。因此,您首先要将它们分为两个不同的类。为每个要实现的类创建一个接口。然后,实现findPrincipal
方法的类可以依赖另一个接口作为构造函数参数,如下所示:
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;
}
}
公共类PrincipalFinder Impl实现PrincipalFinder
{
私人编码器查找器;
公共PrincipalFinder(CodeFinder CodeFinder){
this.codeFinder=codeFinder;
}
公共字符串findPrincipal(列出文档键){
Hashtable codecounts=新的Hashtable();
用于(文档密钥文档:文档密钥){
int x=0;
字符串closestCode=codeFinder.getClosestDocumentCode(document.candidates);
如果(closestCode==null)继续;
整数=0;
if(codeconts.containsKey(closestCode))
count=codeconts.get(closestCode);
if(document.hasKey)
计数+=2;
其他的
count++;
put(closestCode,新整数(thecount));
x++;
}
字符串closestCode=codeFinder.getClosestCode(codeconts);
返回关闭代码;
}
}
现在,创建另一个实现
CodeFinder
接口的类应该很容易,可以手动创建,也可以使用模拟框架创建。然后,您可以控制对getClosestCode
和getClosestDocumentCode
的每次调用的结果,并确保调用这些方法时使用的参数与您希望使用的参数完全相同。我没有深入阅读该方法。但是,如果需要测试私有方法,则表明您的设计有问题。至少。请在下载时注明原因。对我来说这是一个非常有效的问题。你为什么要测试一个private
类?如果要测试它,为什么它是静态的?答案和参考资料中会有很多细节,说明为什么这些关键字不应该出现在您正在测试的方法中。@MK:这可能被认为是太本地化了,尽管这甚至不是投票的内容。非常奇怪。+1:根据我的经验,这个问题总是表明该类实际上应该是两个或更多的类。+1对于重构可能看起来像什么的代码示例来说,“您的设计有问题”是非常没有帮助的。