2014-09-12 123 views
1

我很努力地理解爲什麼我的設置 - 拆卸過程不像我在ScalaTest中所期望的那樣工作。基本上,我的測試代碼如下:ScalaTest:瞭解測試執行順序

class UserManagerTest extends FlatSpec with ManagerBehaviors[User, UserDAO] { 

    "An entity manager" should behave like allFindingManager(UserManager) 

    "An entity manager" should behave like countingManager(UserManager) 
} 


trait ManagerBehaviors[T <: IEntity, D <: AbstractDAO[T]] { 

this: FlatSpec => 

    private def withClearDB(entityManager: BasicManager[T, D], testFunction:() => Unit) = { 
    try { 
     clearDB(entityManager) 
     testFunction() 
    } finally { 
     clearDB(entityManager) 
    } 
    } 

    private def clearDB(manager: BasicManager[T, D]) = { 
    manager.all match { 
     case Some(entities) => for (entity <- entities) manager.remove(entity.getId) 
    } 
    } 

    def allFindingManager(manager: BasicManager[T, D]) { 
    withClearDB(manager, 
    () => it should "properly return all elements in the database for the entity" in { 

     // Add 10 entities to the database 
     for (i <- 1 to 10) manager.persist(manager.defaultEntity) 

     manager.all match { 
      case Some(entities) => assert(entities.length == 10) 
      case None => fail() 
     } 
     }) 
    } 

    def countingManager(manager: BasicManager[T, D]) { 
    withClearDB(manager, 
    () => it should "properly count the number of entities managed" in { 

     // Add 10 entities to the database 
     for (i <- 1 to 10) manager.persist(manager.defaultEntity) 

     assert(manager.count == 10) 
     }) 
    } 
} 

我想到的是下面的順序:

  1. clearDB

  2. allFindingManager

  3. clearDB

  4. clearDB

  5. countingManager

  6. clearDB

當單獨運行,測試按預期工作 - 數據庫是在啓動時被清除,留下空當測試結束。

但是,運行整個UserManagerTest類時,由於某種原因失敗,出現以下:

org.scalatest.exceptions.TestFailedException: 20 did not equal 10 

這樣做的原因是,不知何故,該測試被稱爲對方右後無間斷clearDB調用。我無能爲力,爲什麼會發生這種情況。

當使用調試器並在finally塊內放置斷點時,發現發生了什麼的可能線索:此塊確實運行了兩次,如預期的那樣,但是這發生在BEFORE(!)測試方法執行之前,這使得沒有任何意義:

  1. clearDB

  2. clearDB

  3. clearDB

  4. clearDB

  5. allFindingManager

  6. countingManager

誰能幫助我闡明這一些輕?

+0

我注意到的一件事[在文檔中的「調用貸款夾具方法」](http://www.scalatest。org/user_guide/sharing_fixtures)是你將'withClearDb'包裹在'should'子句外,但是doc使用成語''something'應該在withClearDb {'中做某事「。也許你被這種方式困在DSL機制的齒輪中。 – 2014-09-12 14:45:23

+0

不知道它是否有幫助,但我最終在處理類似問題時使用了BeforeAndAfter特徵 – Azzie 2014-09-12 15:03:19

回答

4

如果更改

def countingManager(manager: BasicManager[T, D]) { 
    withClearDB(manager, 
    () => it should "properly ..." in { 

     // Add 10 entities to the database 
     for (i <- 1 to 10) manager.persist(manager.defaultEntity) 

     assert(manager.count == 10) 
    }) 
} 

def countingManager(manager: BasicManager[T, D]) { 

    it should "properly ..." in withClearDB(manager, 
    () => { 
     // Add 10 entities to the database 
     for (i <- 1 to 10) manager.persist(manager.defaultEntity) 

     assert(manager.count == 10) 
    } 
) 

} 

,並同樣在其他功能,則執行順序將會像你期望的那樣。

+0

事實上,我實際上只是回來並要求您將您的評論置於答案中,因爲這解決了問題。我看到你打敗了我,接受了:)非常感謝。 – csvan 2014-09-12 15:05:05