Мне нужно реорганизовать устаревший код, и я начал с некоторых тестов. Это тестируемый метод:
public static synchronized String getWeekFromDate(Date date) {
String strYyear = new SimpleDateFormat("yyyy").format(date);
String strMonth = new SimpleDateFormat("MM").format(date);
String strWeek = new SimpleDateFormat("ww").format(date);
int month = Integer.parseInt(strMonth);
if (month > 1 && "01".equals(strWeek)) {
int year = Integer.parseInt(strYyear);
return (year + 1) + "01";
}
return new SimpleDateFormat("yyyyww").format(date);
}
Я написал пять тестовых примеров, и все они зеленые. Теперь я хочу его реорганизовать. Состояние if (month > 1 && "01".equals(strWeek)) для меня не имеет смысла. Это можно было бы прочитать так:
Given a date, it's true when the month is not January and the week is the first one in that year
Я прав? Имеет ли это смысл? Я почти уверен, что смогу удалить этот фрагмент кода без последствий.
Мои тестовые примеры (все зеленые):
@RobbyCornelissen Извините, я изменил код вопроса. Отредактировано!
Вместо того, чтобы вручную выбирать пару «случайных» дат, вы можете просто написать цикл, который проверяет даты все за последние 10 лет или около того. Это легко нашло бы контрпримеры. После этого вы можете просто сохранить примеры счетчиков граничных случаев плюс некоторую случайную дату между ними в качестве тестов, которые следует сохранить.




Нет, вы не можете безопасно удалить этот код. Даты в конце года, которые приходятся на первую неделю нового года, соответствуют этому условию.
Рассмотрим следующий случай, когда 31 декабря 2017 года вы получите строку результата 201701:
Date date = new SimpleDateFormat("yyyy/MM/dd").parse("2017/12/31");
String weekYear = new SimpleDateFormat("yyyyww").format(date);
System.out.println(weekYear); // "201701" - WRONG
Однако есть гораздо более элегантное решение, чем код, который у вас есть в настоящее время, основанный на шаблоне SimpleDateFormatнеделя год (Y вместо y):
Date date = new SimpleDateFormat("yyyy/MM/dd").parse("2017/12/31");
String weekYear = new SimpleDateFormat("YYYYww").format(date);
System.out.println(weekYear); // "201801" - CORRECT
При модульном тестировании вы должны в первую очередь обращать внимание на граничные случаи. Такие даты, как первый и последний день года, определенно могут считаться здесь пограничными случаями.
Спасибо за Ваш ответ. Но в вашем примере я получаю не «201801», а «201752».
Я думаю, что разница в выводе может быть связана с часовым поясом. Что вы получите за дату 2015/12/31?
Если я использую 2018/12/31, он отлично работает: возвращает 201901. Хороший момент, большое спасибо!
Да это оно! Спасибо д
Если это вообще возможно, вам следует подумать о переходе на API даты и времени Java 8.
Да, я использую Java 8. Как я могу улучшить его, используя Java 8?
Вот обзор: oracle.com/technetwork/articles/java/…
Что это за язык? Похоже на Java, но я не понимаю, как такие вещи, как
"yyyy".format(date), вообще должны компилироваться. Кроме того, я не вижу причин для синхронизации этого метода.