2012-04-03 60 views
4

我正在嘗試使用Play Framework 2.0和Specs2來測試模型方法。 Global.scala首次使用數據填充數據庫。在一次測試中,我可以使用如下代碼成功測試它:爲什麼java.util.Date對象滿足一個Specs測試但又失敗了?

def dateHelper(str: String): Date = new SimpleDateFormat("MM/dd/yyyy").parse(str) 

"Food model" should { 
    "be retrieved by id" in { 
    val Some(mashedPotatoes) = Food.findById(1000) 

    mashedPotatoes.name must equalTo("Mashed Potatoes") 
    mashedPotatoes.eaten must equalTo(false) 
    mashedPotatoes.id must equalTo(Id(1000)) 
    mashedPotatoes.owner must equalTo(Id(1)) 
    mashedPotatoes.expiry must equalTo(dateHelper("05/21/2012")) 
    } 
} 

該測試通過。但是,如果我嘗試從模型中選擇一個以上的項目,並測試它作爲一個清單:

"return food for test user in " in { 

    running(FakeApplication()) { 
    val testFoods: Seq[Food] = Food.findFoodFor(Id(1)) // Test user's ID is 1 

// This test fails   
    testFoods must equalTo(
     List(
     Food(Id(1001), "Fried Green Tomatoes", false, Id(1), dateHelper("04/21/2012")), 
     Food(Id(1000), "Mashed Potatoes", false, Id(1), dateHelper("05/21/2012")) 
    ) 
    ) 

// This test passes 
    testFoods.head.expiry must equalTo(dateHelper("04/21/2012")) 
    } 
} 

錯誤輸出告訴我,日期字段不相等:

[error] x return food for test user in 
[error]  'Food(1001,Fried Green Tomatoes,false,1,2012-04-21 00:00:00.0), Food(1000,Mashed Potatoes,false,1,2012-05-21 00:00:00.0)' is not equal to 'Food(1001,Fried Green Tomatoes,false,1,Sat Apr 21 00:00:00 EDT 2012), Food(1000,Mashed Potatoes,false,1,Mon May 21 00:00:00 EDT 2012)' (ModelSpec.scala:66) 
[error] Expected: ...se,1,[Sat Apr ]21...00[ EDT 2]0[12]),...1,[Mon May ]21...00[ EDT 2]0[12]) 
[error] Actual: ...se,1,[2012-04-]21...00[.]0[]),...1,[2012-05-]21...00[.]0[]) 

有我錯過了,在這裏?

編輯:它看起來像是數據庫架構,它將過期列設置爲時間戳類型,而不是類型日期。

更多有用的前瞻性信息在這裏:java.util.Date vs java.sql.Date

+0

如果你這樣做:testFoods.head mustToTo(Food(Id(1001),「Fried Green Tomatoes」,false,Id(1),dateHelper(「04/21/2012」)))。這是否也會失敗? – Christian 2012-04-03 13:48:35

+0

你確實錯過了一些東西:喬達時間;-)它可能不是問題,但是像Scala這樣的語言鼓勵不可變性,喬達時間比SimpleDateFormat更適合。無論是什麼問題,我都很好奇SDF是不是罪魁禍首...... – virtualeyes 2012-04-03 13:55:35

回答

3

這個問題可能是因爲如何將數據從數據庫加載。我敢打賭它使用java.sql.Timestamp而不是java.util.Date

scala> val date = dateHelper("05/12/1974") 
d: java.util.Date = Sun May 12 00:00:00 CDT 1974 

scala> val dbDate = new java.sql.Timestamp(d.getTime) 
dbDate: java.sql.Timestamp = 1974-05-12 00:00:00.0 

scala> date == dbDate 
res6: Boolean = true 

scala> dbDate == date // prepare to be amazed! 
res5: Boolean = false 

如果你讀the fine print in the Javadoc,你會發現這個可愛的小聲明:

鑑於Timestamp類和上述java.util.Date類之間的差別,所以建議代碼不會將時間戳值一般視爲java.util.Date的實例。 Timestamp和java.util.Date之間的繼承關係實際上表示實現繼承,而不是類型繼承。

您的ORM映射或數據庫模式可能有問題。列是否爲DATETIMESTAMPTIMESTAMP WITH TIMEZONE?如果它是DATE,你應該將其映射到java.sql.Date,這應該比較正確。如果它是TIMESTAMP WITH TIMEZONE,那麼你的dateHelper應該建立Timestamp s。如果是TIMESTAMP,祝你好運,因爲數據庫將丟失時區信息。

+0

看起來像是架構。該架構已設置爲時間戳。我試着將它設置爲日期並重新運行一切。現在全是綠色的。 我也發現這看起來像它有幫助的相關信息(和另一個插件喬達時間):http://stackoverflow.com/questions/2305973/java-util-date-vs-java-sql-date – 2012-04-03 16:58:50