4

Play Framework 2.0 と Specs2 を使用してモデル メソッドをテストしようとしています。Global.scala は、最初の実行時に DB にデータを入力します。あるテストでは、以下のようなコードを使用して正常にテストできます。

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

ここで私が見逃しているものはありますか?

編集:有効期限列を日付型ではなくタイムスタンプ型に設定したのはDBスキーマのようです。

ここでより役立つ情報: java.util.Date vs java.sql.Date

4

1 に答える 1

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

Javadoc の細字部分を読むと、次の素敵なステートメントが見つかります。

上記の Timestamp クラスと java.util.Date クラスの違いにより、コードは Timestamp 値を一般的に java.util.Date のインスタンスとして表示しないことをお勧めします。Timestamp と java.util.Date の間の継承関係は、型の継承ではなく、実際には実装の継承を示しています。

ORM マッピングまたはデータベース スキーマに問題がある可能性があります。列はDATEまたはTIMESTAMPまたはTIMESTAMP WITH TIMEZONEですか? それが の場合、それDATEを にマップするjava.sql.Date必要があります。これは正しく比較されます。の場合はTIMESTAMP WITH TIMEZONE、 sdateHelperを構築する必要がありますTimestamp。の場合TIMESTAMPは、データベースのタイムゾーン情報が失われるため、幸運を祈ります。

于 2012-04-03T14:41:59.117 に答える