[Resolved] Задать дату для тестов. (Java)

Всем привет. Тестирую выгрузку отчетов, проверку содержимого. В разные дни данные разные. Необходимо реализовать так, чтобы тесты думали что они всегда работают 10-го января например. Подскажите, как в Java явно задать дату? Пока только так сделал:

Date currentDate = new Date();
Long time = currentDate.getTime();
long anotherDate = -3;
time = time + (60 * 60 * 24 * 1000 * anotherDate);
currentDate = new Date(time);

Задача не до конца сформулирована. Что значит “чтобы тесты думали”? Вам нужно подсовывать разную дату одному и тому же тесту через DataProvider, или что? Каким образом происходит выгрузка отчетов? Приложение само определяет дату, исходя из текущего системного времени, или все же вы вольны сами выбирать нужную?

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

Ну тогда вам нужно явно устанавливать новое системное время, либо вытягивать репорт за конкретную дату средствами самого приложения - дергая соответствующий сервис.

В плане смены даты не все так тривиально. Из того, что видел на просторах паутины, предлагают использовать JNI.

В плане обращения к сервису получения репорта, вам достаточно узнать у разработчиков нужный endpoint (который наверняка принимает параметр текущей даты) и отправить соответствующий реквест. Далее, просто в респонсе получите репорт и работаете с ним, как прежде.

1 лайк

КМК, уже неправильный подход. Зачем тестировать одно и то же? Тестировать корректность блока обработки данных?

На мой взгляд, этого мало. Можно и нужно совместить и сделать чуть сложнее, а заодно и проверить корректность выборки по дате. Например, сделать собственное обращение к БД и взять данные на текущий момент (дату и время лучше, если возможно, использовать одни и те же, что использует приложение, зачем - думаю, объяснять не надо) и сравнивать всё в текущем времени. Это может выявить баги, вряд ли находимые при прогонах одного и того же набора данных с уже известным содержимым со всеми известными его свойствами.

Calendar cal = Calendar.getInstance();
		
cal.set(2014, 00, 10);
cal.set(Calendar.HOUR_OF_DAY,18);
cal.set(Calendar.MINUTE,30);
cal.set(Calendar.SECOND,0);

Date date = cal.getTime();

Не читайте темы по диагонали:

Да, в Java это проблема. Сэмулировать другое время невозможно. Поэтому мы в коде вместо “new Date()” вызываем “DateUtils.now()”, который в лайве возвращает текущую дату, а в тестах возвращает замоканную. Лучший возможный компромисс.

1 лайк

Лучший возможный компромисс - это когда налажена система Dependency injection, будь-то Guice или Spring, и методы или конструктор принимаю Clock интерфейс. В тестах внедряется мок, который ведет себя так, как это нужно просимулировать.

Можно и так. Но если внимательно сравнить эти два варианта , получается, что вариант со статическим методом требует меньше кода.

Откуда DateUtils знает какое значение (настоящее или замоканое) возвращать? Наверное есть флаг какой-нибудь или другой метод, который задает фейковое значение. Т.е. получается, что в Продакшн идет код вместе с кодом, который нужен только для тестов - а это уже не правильно.
И еще, “меньше кода” не всегда лучше. Dependency injection не просто так изобрели.