Сравнение дат с тестированием JUnit

Привет, я новичок на сайте и имею проблему с моим приложением, используя тестирование JUnit. Моя проблема в том, что когда я пытаюсь сравнить метод Date с самим собой, он всегда терпит неудачу. Я напечатал объект Date в тесте, чтобы увидеть проблему, и всегда заканчиваюсь именем пакета и случайными буквами. Вот конструктор Date:

public class Date
{
SimpleDateFormat dformat = new SimpleDateFormat("dd-MM-yyyy");

private int day;
private int month;
private int year;

public Date() 
{
    String today;
    Calendar present = Calendar.getInstance();

    day = present.get(Calendar.DAY_OF_MONTH);
    month = present.get(Calendar.MONTH);
    year = present.get(Calendar.YEAR);

    present.setLenient(false);
    present.set(year, month - 1, day, 0, 0);

    today = dformat.format(present.getTime());
    System.out.println(today);
}

Вот мой тест:

@Test 
public void currentDay()
{
    Date current = new Date();
    System.out.println(current);
    assertEquals("today:", current, new Date());
}

Однако результат всегда терпит неудачу, и я получаю что-то вроде:

[email protected]

Любая помощь будет оценена по достоинству.

Ответ 1

Объект по умолчанию равен объекту, который сравнивает ячейки памяти. Если оба объекта указывают на одно и то же место в памяти, тогда только он будет печатать равные, что не относится к вашей программе. поскольку они указывают на два разных местоположения памяти, они всегда дают ложные значения, которые ожидаются.

Если вы считаете, что ваш метод assertEquals (date1, date2) должен возвращать true, поскольку содержимое равно, вы должны переопределить метод equals. И когда вы переопределяете равные, вы должны переопределить метод hashcode(), чтобы убедиться, что вы можете уверенно использовать экземпляр класса в качестве ключа в любой коллекции на основе хэширования, например HashMap или HashSet.

Вот ссылка, объясняющая, как переопределить метод equals() и hashcode()

http://javarevisited.blogspot.in/2011/02/how-to-write-equals-method-in-java.html

И не называйте свой класс таким же, как любой класс API, как предложил Jon Skeet.

Надеюсь это поможет.

Ответ 2

Переопределить метод равных по умолчанию не требуется. Вы просто используете Date.compareTo() для сравнения двух объектов даты.

Ответ 3

Хотя ответ @Shrikanth отвечает на этот вопрос, эта проблема также возникает с обычными объектами Date. Два возможного решения приведено здесь:

  1. Для сравнения дат используйте DateUtils.truncate (или даже DateUtils.truncatedEquals). Это то, что вы можете использовать в методе equals или для обычных объектов Date непосредственно в вас assertEquals/assertTrue.

    assertEquals(DateUtils.truncate(date1,Calendar.SECOND), 
                 DateUtils.truncate(date2,Calendar.SECOND));
    
  2. Не проверяйте, совпадают ли даты, но находятся ли они достаточно близко друг к другу (для JUnit test sake):

    assertTrue("Dates aren't close enough to each other!", 
               Math.abs(date2.getTime() - date1.getTime()) < 1000);
    

Ответ 4

Обновление Проект Joda-Time теперь находится в режиме обслуживания, при этом команда рекомендует переносить классы java.time.


Такая работа намного проще с библиотекой Joda-Time, а не с печально известными классами Date/Calendar.

Пример кода в Joda-Time 2.3

Настройте некоторые данные...

DateTime now = new DateTime();
DateTime yesterday = now.minusDays( 1 );
DateTime nowAgain = new DateTime( now.toString() ); // New object, but same value inside.

Сравнить...

boolean isNowEqualToYesterday = now.equals( yesterday );
boolean isNowEqualToNowAgain = now.equals( nowAgain );

Сбросить консоль...

System.out.println( "now: " + now );
System.out.println( "yesterday: " + yesterday );
System.out.println( "nowAgain: " + nowAgain );

System.out.println( "isNowEqualToYesterday: " + isNowEqualToYesterday );
System.out.println( "isNowEqualToNowAgain: " + isNowEqualToNowAgain );

При запуске...

now: 2014-02-06T01:31:43.157-08:00
yesterday: 2014-02-05T01:31:43.157-08:00
nowAgain: 2014-02-06T01:31:43.157-08:00
isNowEqualToYesterday: false
isNowEqualToNowAgain: true

Конвертировать

Вы можете конвертировать в и из Joda-Time, если это необходимо.

org.joda.time.DateTime dateTime = new DateTime( date ); // From Date to DateTime.
java.util.Date date = dateTime.toDate();  // From DateTime to Date.

Ответ 5

Вам нужно переопределить как equals(), так и toString(). Если вы переопределяете equals, всегда переопределяйте hashcode(), чтобы ваши карты работали правильно.