我正在编写与数据库交互的测试,并且希望进行某种特定于每个测试的设置和拆卸。这就是我目前所拥有的:
"my test" in {
// Use anorm to populate the database
Db.withConnection {
SQL"INSERT INTO ...".execute()
// Do some tests
foo must equal 1
bar must equal 2
// Remove the test data
SQL"DELETE FROM ...".execute()
}
}
这种方法的问题在于,如果其中一个测试失败,那么执行将暂停,测试数据永远不会从数据库中删除。
答案 0 :(得分:0)
假设您正在使用specs2,您可以为每个测试创建Around
范围:
"my test" in DatabaseSetup {
// Do some tests
foo must equal 1
bar must equal 2
}
trait DatabaseSetup extends org.specs2.mutable.Around {
def around[T: org.specs2.execute.AsResult](t: => T) = {
Db.withConnection {
// Insert data
}
val result = org.specs2.execute.AsResult(t)
Db.withConnection {
// Remove data
}
result
}
}
无论如何,这可能很难维护,这样的结构可能会显示您的生产代码或测试代码的某些问题。你应该问问自己为什么不能重用数据库设置。
答案 1 :(得分:0)
specs2
进行测试,那么@ marcospereira的答案很有效,但我使用的是PlaySpec
。以下示例:
rowID
,以便可以在其他任何地方使用rowID
,从数据库中删除相应的行。
import anorm._
import org.scalatest.{BeforeAndAfter, DoNotDiscover}
import org.scalatestplus.play.{ConfiguredServer, PlaySpec}
import play.api.db.DB
import play.api.libs.json.Json
import play.api.libs.ws.WS
import play.api.test.Helpers._
@DoNotDiscover
class ExampleSpec extends PlaySpec with BeforeAndAfter with ConfiguredServer {
val baseAddress = s"http://localhost:$testServerPort/"
var rowID: Int = _
before {
DB.withConnection { implicit connection =>
rowID = SQL"INSERT INTO some_table (col1, col2) VALUES('v1', 'v2')".executeInsert(SqlParser.scalar[Int].single)
}
}
after {
DB.withConnection { implicit connection =>
SQL"DELETE FROM some_table WHERE id = $rowID".execute()
}
}
"GET my/endpoint/{id}" should {
"return a 200" in {
val address = baseAddress + s"my/endpoint/$rowID"
val response = await(WS.url(address).get())
response.status mustEqual OK
}
}
}