Может ли это условие быть оценено как «истинное» в любом случае?

Мне нужно реорганизовать устаревший код, и я начал с некоторых тестов. Это тестируемый метод:

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

Я прав? Имеет ли это смысл? Я почти уверен, что смогу удалить этот фрагмент кода без последствий.

Мои тестовые примеры (все зеленые):

  • Учитывая 2018-01-03, он должен вернуть "201801"
  • Учитывая 2018-02-01, он должен вернуть "201805".
  • Учитывая значение 2018-08-15, он должен вернуть "201833".

Что это за язык? Похоже на Java, но я не понимаю, как такие вещи, как "yyyy".format(date), вообще должны компилироваться. Кроме того, я не вижу причин для синхронизации этого метода.

Robby Cornelissen 11.05.2018 10:24

@RobbyCornelissen Извините, я изменил код вопроса. Отредактировано!

Héctor 11.05.2018 10:31

Вместо того, чтобы вручную выбирать пару «случайных» дат, вы можете просто написать цикл, который проверяет даты все за последние 10 лет или около того. Это легко нашло бы контрпримеры. После этого вы можете просто сохранить примеры счетчиков граничных случаев плюс некоторую случайную дату между ними в качестве тестов, которые следует сохранить.

Giacomo Alzetta 11.05.2018 11:01
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
3
34
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Нет, вы не можете безопасно удалить этот код. Даты в конце года, которые приходятся на первую неделю нового года, соответствуют этому условию.

Рассмотрим следующий случай, когда 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».

Héctor 11.05.2018 11:03

Я думаю, что разница в выводе может быть связана с часовым поясом. Что вы получите за дату 2015/12/31?

Robby Cornelissen 11.05.2018 11:08

Если я использую 2018/12/31, он отлично работает: возвращает 201901. Хороший момент, большое спасибо!

Héctor 11.05.2018 11:08

Да это оно! Спасибо д

Héctor 11.05.2018 11:08

Если это вообще возможно, вам следует подумать о переходе на API даты и времени Java 8.

Robby Cornelissen 11.05.2018 11:17

Да, я использую Java 8. Как я могу улучшить его, используя Java 8?

Héctor 11.05.2018 11:19

Вот обзор: oracle.com/technetwork/articles/java/…

Robby Cornelissen 11.05.2018 11:20

Другие вопросы по теме