2014-09-12 115 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