2016-03-01 46 views
0

我正在編寫與數據庫交互的測試,並且想要進行某種特定於每個測試的設置和拆卸。這是我目前有:每個測試函數後運行不同的代碼

"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

@ marcospereira的答案效果很好,如果您使用specs2進行測試,但我使用的是PlaySpec。下面的例子:

  1. 插入一行到數據庫中,
  2. 設置rowID因此它可以在其他地方使用,
  3. 發出GET請求,這取決於rowID服務器,
  4. 測試結果,
  5. 從數據庫中刪除相應的行。

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

,這可能是很難維護和這樣的結構可能是揭示了一些問題,你的產品代碼或你的測試代碼。你應該問自己爲什麼你不能重用數據庫設置。

+0

我的應用程序是一個REST API,所以我只是想通過把數據庫中的一些數據,然後打端點(我知道會發生什麼,因爲我只是把數據)來測試終端,然後刪除這些數據,這樣我就不會污染任何其他測試。有沒有更好的辦法? – Tyler

+0

好吧,如果測試集中在一個資源上,我不明白爲什麼每個測試「方法」都需要不同的設置。我的意思是,如果你有'PersonApiSpec','CountryApiSpec','LessonApiSpec'等,我認爲這會給你足夠的隔離。當然,這個意見是基於我可以從這個問題中推斷出來的。 :-) – marcospereira

+0

無論如何,我的答案中的四周特徵可以用於這兩種情況。 – marcospereira

相關問題