下面是我必须为其编写单元测试的一个类中的示例switch语句。我从下面的代码中删除了每种情况下的逻辑。
switch (insurance.getInsuranceType()) {
case None:{
break;}
case Health: {
break;}
case Auto:{
break;}
case WorkersCompensation:{
break;}
default:{}
}
我必须覆盖每个交换机路径,但要到达此交换点以便进行测试,我必须放置10个小时和相应的验证语句(我使用Mockito进行模拟)。为了覆盖每个路径,我可以选择编写与switch语句中的情况一样多的函数(对于各种InsuranceType
数据),或者我编写单个函数并通过更改InsuranceType
数据来重复相同的代码。测试代码以两种方式复制,第二种方式更容易出错,以验证对模拟对象的调用。我的问题是关于任何其他方式(这有助于避免重复的代码和清理测试代码)以及经验丰富的开发人员如何在单元测试中处理switch语句(因为我的代码中存在10个案例的情况)?代码是由其他一些开发人员编写的,我被要求编写单元测试以增加测试覆盖率并进行额外的单元测试。我需要知道是否存在关于多个逻辑分支的通用实践(不一定只有switch语句,但有时候有多个if - else if - else逻辑和3-4级深度嵌套条件)。 insurance.getInsuranceType()是一个枚举。
请建议。
答案 0 :(得分:5)
免责声明:这是一个意见,但我将其作为答案,因为评论时间不足以完全解释自己。
通常,switch
语句表示代码设计不佳。在上述情况中,例如:
public Coverage returnCoverage() { // I'm just making up a method name here
switch (insurance.getInsuranceType()) {
case None: {
...
break;
}
case Health: {
...
break;
}
...
}
}
...看起来你有一些方法,其逻辑分支在保险类型上。这向我表明你的保险类型应该具有逻辑。例如:
public interface InsuranceType { // not enum
Coverage getCoverage();
}
public class NoInsurance implements InsuranceType {
public Coverage getCoverage() {
...
}
}
public class HealthInsurance implements InsuranceType {
public Coverage getCoverage() {
...
}
}
// etc.
然后,您的Insurance
对象将包含InsuranceType
的实例,就像它当前一样。您可以使用enum
s执行相同的操作 - 按枚举值实现不同的方法 - 但它有点混乱。
如果对所有switch
语句执行此操作,您应该会看到一个连贯的InsuranceType
域对象开始出现,您应该开始看到可以移动到该类层次结构中的其他代码。此外,如果您将来需要添加新类型的保险,您不必搜索所有代码,试图查找您开启的所有地点InsuranceType
- 相反,您只需创建一个新的实现类,一切都神奇地起作用。
要回答有关测试的问题,如果您执行上述操作,那么您的switch
声明就会消失。因此,您可以单独测试每个InsuranceType
,而无需进行大量的模拟。
高度嵌套的if语句也是如此。将它们分解为单独的方法,并将逻辑移动到它所属的位置,并将其合并。你通常会发现大量的剪切' n'粘贴代码的分支非常相似。如果您使用IDE,请查找提取方法重构,并确保选择"检测重复项"选项。希望您可以减少必须维护的代码量,以及代码的复杂性,并让下一个开发人员保持更好的状态!
希望有所帮助!