让我解释一下问题情景。我的任务是修改复杂的函数testFunc(),如下所示。
public String testFunc() {
String a = func1();
String b = func2(a);
String c = func3(b);
return c;
}
private String func1(){
return "hello";
}
private String func2(String p1){
return "a" + p1;
}
private String func3(String p1){
return "b" + p1;
}
我修改了testFunc方法并包含了我的逻辑。但作为一名优秀的开发人员,我希望为我编写的额外逻辑编写无条件测试。 但我没有时间也没有耐心来测试整个方法。我希望只测试我添加的逻辑。
public String testFunc() {
String a = func1();
String b = func2(a);
String c = func3(b);
String d = func4(c)
return d;
}
protected final String func4(String p1) {
return "1" + p1;
}
将func4作为受保护的最终方法使我有意义,以便我可以彻底地对逻辑进行单元测试。或者编码实践不好?
答案 0 :(得分:2)
我会将其打包为私有,这比受保护更具限制性。如果您已经在项目中使用了Guava,您甚至可以使用@VisibleForTesting
注释该方法,以明确您的意图:
@VisibleForTesting final String func4(String p1) {
//...
}
最后,包私有方法不会暴露给外部世界,也不属于您的API,因此它不会破坏封装。
答案 1 :(得分:2)
这是一种不好的做法。私有/受保护的方法应该通过调用它们的公共方法来测试。通过将访问修饰符更改为package-private,您实际上是将实现细节暴露给其他类,从而减少了封装。
如果结果很难,你应该考虑重新设计公共API。
答案 2 :(得分:0)
更改单元测试方法的可见性不是一个好习惯。
如果您在项目中使用Spring,则可以使用ReflectionTestUtils org.springframework.test.util.ReflectionTestUtils
(简化反思)来访问私有方法和属性。
如果您不想使用Spring,那么您必须进行Java反射。
答案 3 :(得分:0)
嗯,我开始说问题中的两句话与我有些矛盾:
但作为一名优秀的开发人员,我希望为我编写的额外逻辑编写单元测试。
和
但我没有时间也没有耐心来测试整个方法。一世 我希望只测试我添加的逻辑。
你是一个优秀的开发人员,自上而下做事,或者没有耐心,然后没有什么可以帮助你。
回答你的问题,揭露不能重复使用的私人方法,这是非常糟糕的做法,因此不是一种好的方法。虽然您所做的更改不能脱离课程的上下文,但您执行了此更改,例如您有:
class MyClass {
public String testFunc() {
String a = func1();
String b = func2(a);
String c = func3(b);
return c;
}
private String func1(){
return "hello";
}
private String func2(String p1){
return "a" + p1;
}
private String func3(String p1){
return "b" + p1;
}
}
因此,有一些可能的方法可以使用新功能扩展此逻辑,例如,您希望decorate初始类具有新功能并在其中添加新功能,例如:
class MyNewClass extends MyClass{
private MyClass delegate;
public MyNewClass(MyClass delegate) {
this.delegate = delegate;
}
public String testFunc() {
String c = delegate.testFunc();
return func4(c);
}
private final String func4(String p1) {
return "1" + p1;
}
}
现在,您可以通过mocking MyClass
实例编写单元测试,并仅检查新添加的逻辑。
另一种可能的替代方法是将新功能提取到自己的类中,并仅为其编写测试。