2014-02-05 24 views
11

您好,我是該網站的新手,並且在使用JUnit測試的應用程序中遇到問題。我的問題是,當我試圖比較Date方法和它自己總是失敗。我在測試中打印Date對象以查看問題,並始終以包名和隨機字母結束。下面是日期構造函數:將日期與JUnit測試進行比較

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] 

任何幫助將是讚賞。

+10

第一個建議:不要給你自己的類使用與'java.util'中相同的名字。 –

+3

下一個建議:如果你要斷言兩個不同的對象是相等的,你需要重寫'equals'(和'hashCode',爲了理智)。 –

+2

下一個建議:如果你想要一個體面的字符串表示,重寫'toString'。 –

回答

4

默認等於對象比較內存位置。如果兩個對象都指向相同的內存位置,那麼只有它會打印等於在程序中不是這種情況。因爲它們指向兩個不同的存儲位置,所以它總是給出錯誤,這是預期的。

如果您覺得您的assertEquals(date1,date2)方法應該返回true,因爲內容相同,那麼您應該重寫equals方法。當你重寫equals時,你應該重寫hashcode()方法,以確保你可以放心地使用你的類實例作爲任何基於散列的集合(如HashMap或HashSet)中的鍵。

這裏是()的鏈接解釋如何重寫equals和hashCode()方法

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

不要命名您的類與任何API類爲喬恩斯基特建議。

希望這會有所幫助。

+0

非常感謝您,通讀它並將其實施到我的代碼中,並且它非常棒! – user3276602

+0

歡迎您:) –

0

您需要重寫equals()和toString()。如果您覆蓋equals,則始終覆蓋hashcode(),以便您的地圖可以正常工作。

1

更新 Joda-Time項目現在處於維護模式,團隊建議遷移到java.time類。


這方面的工作是與Joda-Time庫,而不是出了名的麻煩日期/ Calendar類容易得多。

示例代碼中喬達時間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 

轉換

可以進出喬達 - 時間的轉換,如果需要的話。

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

雖然@Shrikanth的答案解決了這個問題,但這個問題也出現在正常的Date對象中。兩種可能的解決方案,給出here

  1. 。利用DateUtils.truncate(甚至DateUtils.truncatedEquals)的比較的日期。這是你可以在你的equals方法中使用的東西,或者直接在你的assertEquals/assertTrue中用於普通的Date對象。

    assertEquals(DateUtils.truncate(date1,Calendar.SECOND), 
          DateUtils.truncate(date2,Calendar.SECOND)); 
    
  2. 不檢查日期是否是相同的,但它們是否足夠接近海誓山盟(用於JUnit測試的緣故):

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

對於解決方案2:我認爲將'date2.getTime() - date1.getTime()'包裝在'Math.abs()'中,然後再進行比較,這很有幫助。然後,如果'date1'或'date2'是較舊的日期,它就會工作。 – peitek

+1

雖然您知道新的Date()將始終比先前創建的日期晚,但我確實認爲它使比較更加健壯,所以我編輯了它。 –

+0

我認爲最好使用'.round'而不是'.truncate',在兩個日期關閉幾毫秒的情況下,它們可以被截斷爲不同的秒數。這導致偶爾失敗的測試。採用四捨五入的方法,這不是問題。 assertEquals(DateUtils.round(date1,Calendar.SECOND), DateUtils.round(date2,Calendar.SECOND));'' – madcow

6

重寫默認的equals方法不必要。您只需使用Date.compareTo()來比較兩個日期對象。

相關問題