Java新手如何通过测试方法定位DayOfYear代码中的Bug?
排查DayOfYear类的Bug及测试方法
一、从这些测试用例入手排查
先从简单明确的用例开始验证,逐步覆盖边界和特殊情况:
- 基础非闰年用例:
- 1月1日:
dayOfYear(1, 1, 2023)应返回1,原代码直接返回1,正确。 - 2月28日:
dayOfYear(2, 28, 2023)应返回59,原代码计算28+31=59,正确。 - 3月1日:
dayOfYear(3, 1, 2023)应返回60,原代码计算1+59=60,正确。
- 1月1日:
- 闰年特殊用例:
- 2024是闰年,3月1日:
dayOfYear(3, 1, 2024)正确结果应为61,但原代码返回60,直接暴露第一个Bug。 - 闰年12月31日:正确结果是366,原代码返回31+334=365,少1天。
- 2024是闰年,3月1日:
- 无效参数用例:
- 输入
dayOfYear(0, 1, 2023)(月份0),原代码返回1,显然错误;输入dayOfYear(2, 30, 2023)(非闰年2月30日),原代码返回30+31=61,这是不存在的日期,代码未做校验。
- 输入
二、代码中的具体Bug
未处理闰年的3-12月日期
原代码所有3月及以后的月份累加值都是按2月28天计算的,闰年时2月有29天,导致这些月份的计算结果都少1天。比如闰年3月1日,正确累计天数是31(1月)+29(2月)+1=61,原代码用了31+28=59的累加值,结果为60。缺少参数合法性校验
代码没有检查:- 月份是否在1-12范围内;
- 日期是否符合当月实际天数(比如4月最多30天,非闰年2月最多28天)。
输入无效参数时,代码会返回毫无意义的错误结果,而非提示参数非法。
手动累加的冗余代码易出错
每个月份的累加值都是手动计算的(比如31 + 28 + 31 + 30),这种写法不仅冗余,一旦计算失误(少加/多加天数),就会导致对应月份的结果全部错误,维护性极差。
三、修复建议
public class DayOfYear { public static int dayOfYear(int month, int dayOfMonth, int year) { // 参数合法性校验 if (month < 1 || month > 12) { throw new IllegalArgumentException("月份必须在1-12之间"); } int maxDay = getMaxDayOfMonth(month, year); if (dayOfMonth < 1 || dayOfMonth > maxDay) { throw new IllegalArgumentException("日期不符合当月天数"); } // 非闰年各月累计天数(索引对应月份,0位占位) int[] nonLeapCumulativeDays = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}; int cumulative = nonLeapCumulativeDays[month - 1]; // 闰年且月份大于2时,额外加1天 if (isLeapYear(year) && month > 2) { cumulative += 1; } return cumulative + dayOfMonth; } // 判断闰年 private static boolean isLeapYear(int year) { return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0); } // 获取当月最大天数 private static int getMaxDayOfMonth(int month, int year) { return switch (month) { case 2 -> isLeapYear(year) ? 29 : 28; case 4, 6, 9, 11 -> 30; default -> 31; }; } }
内容的提问来源于stack exchange,提问作者Samuel Karim
相关产品推荐
相关产品推荐

