2012-04-03 10 views
4

Ich versuche, eine Modellmethode mit Play Framework 2.0 und Specs2 zu testen. Global.scala füllt den DB beim ersten Lauf mit Daten. In einem Test kann ich es erfolgreich mit Code wie unten testen:Warum erfüllt ein java.util.Date-Objekt einen Spezifikationstest, aber einen anderen?

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")) 
    } 
} 

Dieser Test besteht. Aber wenn ich versuche, aus dem Modell mehr als ein Element aus, und testen Sie es als Liste:

"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")) 
    } 
} 

Der Fehlerausgang sagt mir, dass die Datumsfelder sind nicht gleich:

[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[]) 

Gibt es etwas, das ich vermisse, hier?

Bearbeiten: Es sieht so aus, als ob es das DB-Schema war, das die Ablaufspalte auf den Typ Zeitstempel gesetzt hatte, statt auf Datum.

Hilfreicher schau Informationen hier: java.util.Date vs java.sql.Date

+0

Was passiert, wenn Sie tun: testFoods.head muss equalTo (Essen (Id (1001), "Fried Green Tomatoes", falsch, Id (1), dateHelper ("04/21/2012"))). Scheitert das auch? – Christian

+0

fehlt dir tatsächlich etwas: Joda Time ;-) Es mag nicht das Problem sein, aber in einer Sprache wie Scala, die Unveränderlichkeit fördert, passt Joda Time besser als SimpleDateFormat. Was auch immer das Problem ist, ich bin gespannt, ob SDF der Schuldige ist ... – virtualeyes

Antwort

3

Das Problem ist wahrscheinlich, weil, wie die Daten aus der Datenbank geladen wird. Ich wette, es ist java.sql.Timestamp anstelle von 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 

Wenn Sie the fine print in the Javadoc lesen, können Sie diese nette kleine Erklärung finden:

Aufgrund der Unterschiede zwischen der Timestamp-Klasse und der Klasse java.util.Date oben erwähnt, ist es empfehlenswert, Timestamp-Werte werden generisch nicht als Instanz von java.util.Date angezeigt. Die Vererbungsbeziehung zwischen Timestamp und java.util.Date steht für die Implementierungsvererbung und nicht für die Vererbung.

Möglicherweise ist in Ihrem ORM-Mapping oder Ihrem Datenbankschema etwas nicht in Ordnung. Ist die Spalte a DATE oder TIMESTAMP oder TIMESTAMP WITH TIMEZONE? Wenn es DATE ist, sollten Sie das auf java.sql.Date abbilden, das sollte richtig vergleichen. Wenn es TIMESTAMP WITH TIMEZONE ist, dann sollte Ihr dateHelperTimestamp s bauen. Wenn es TIMESTAMP ist, viel Glück, da die Datenbank Zeitzoneninformation verloren hat.

+0

Sieht aus wie es das Schema war. Das Schema wurde auf Zeitstempel festgelegt. Ich habe versucht, es auf den neuesten Stand zu bringen und alles neu zu starten. Jetzt ist alles grün. Ich fand auch das, was aussieht, als hätte es hilfreiche Informationen (und einen anderen Stecker für Joda-Zeit): http://StackOverflow.com/Questions/2305973/Java-Util-Date-VS-Java-Sql-Date –

Verwandte Themen