我正在尝试使用Play Framework 2.0和Specs2测试模型方法。 Global.scala在首次运行时使用数据填充数据库。在一次测试中,我可以使用以下代码成功测试它:
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 :(得分: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类之间存在差异,因此建议代码不要将Timestamp值一般视为java.util.Date的实例。 Timestamp和java.util.Date之间的继承关系实际上表示实现继承,而不是类型继承。
您的ORM映射或数据库架构可能有问题。该列是DATE
还是TIMESTAMP
还是TIMESTAMP WITH TIMEZONE
?如果是DATE
,您应该将其映射到java.sql.Date
,这应该正确比较。如果是TIMESTAMP WITH TIMEZONE
,那么您的dateHelper
应该构建Timestamp
。如果它是TIMESTAMP
,祝你好运,因为数据库将丢失时区信息。