创建测试范围/上下文以播种数据并运行应用程序,Scala Play Framework 2

Posted

技术标签:

【中文标题】创建测试范围/上下文以播种数据并运行应用程序,Scala Play Framework 2【英文标题】:Creating Test Scope/Context to seed data and run application, Scala Play Framework 2 【发布时间】:2015-07-08 22:29:39 【问题描述】:

我在找出最好的方法来创建一种简单的方法来测试我的一些以数据库为中心的应用程序代码时遇到了一些麻烦。也许我对更多 OO 语言有偏见,但我想做的是启动应用程序,为数据库播种,将播​​种数据传递给测试,然后清理数据库。我试图使用 before 和 after 块,但遇到了有关延迟初始化和其他竞争条件的各种问题。在文档中,您可以使用 setupData 和 deleteData,但它不提供将数据传递给实际测试的机会。有什么办法可以实现吗?

这是我正在使用的包装器示例:

abstract class WithUserData extends WithApplication 

    var user = null

    override def around[T: AsResult](t: => T): Result = super.around 
      setupData()
      t
      deleteData()
    

    def setupData() 
      Logger.info("Running Before")
      val passwordInfo = PasswordInfo("bcrypt", "$2a$10$at8N/GZHKDbHLh6er.UsbOUjVqx.IGebO2Wc7EmmD2m4tOlin7EAG")
      val u = User(new IdentityId("harrypotter@naytev.com", UsernamePasswordProvider.UsernamePassword), "Harry",
        "Potter", "Harry Potter", Option("harrypotter@naytev.com"), None, AuthenticationMethod.UserPassword,
        None, None, Some(passwordInfo), None, None, "", Subscription.free, None, None, None, List(), None)

      User.save(u)
      Logger.info(s"Before User is before saving : var $user --- variable $u")
      user = u
      Logger.info(s"variable user is $user")
    
    def deleteData(): Unit =
      Logger.info(s"After User is ->  $user")
      Logger.info("Removing the user")
      User.remove(user)
    

然后在我的测试中,我很想像这样使用它:

"with wrong password will not allow user to be logged in" in new WithUserData
    Logger.info(s"Running test 1 with User $user")
    val fakeRequest = FakeRequest(POST, "/authenticate/userpass", FakeHeaders(), "").withFormUrlEncodedBody(("email" , user.email.get), ("password", "Blah"))

    val request = route(fakeRequest).get

    status(request) must equalTo(BAD_REQUEST)

上面的代码不起作用,并且会给出关于用户为空的奇怪错误,即使之前是先运行的。我有什么方法可以传递保存的用户对象吗?我希望不必每次测试都查询对象。它看起来像很多样板,应该在前后处理。

任何帮助将不胜感激!

谢谢,

迈克

【问题讨论】:

【参考方案1】:

关注http://docs.scala-lang.org/tutorials/FAQ/initialization-order.html

你可以用蛋糕图案之类的东西

case class User(id: BigInt, name: String)

trait UserRepositoryComponent 
  def userLocator: UserLocator
  trait UserLocator 
    def getUser: User
    def removeUser(user: User)
  


trait UserTestRepositoryComponent extends UserRepositoryComponent 
  def userLocator = new  UserTestLocator

  class UserTestLocator extends UserLocator 
    override def getUser: User = User(1, "test user")

    override def removeUser(user: User): Unit = ()
  


trait UserRealRepositoryComponent extends UserRepositoryComponent 
  def userLocator = new UserRealLocator
  class UserRealLocator extends UserLocator 
    override def getUser: User = User(1, "real user")

    override def removeUser(user: User): Unit = ()
  


trait UserServiceComponent 
  this: UserRepositoryComponent =>
  def getUser: User = userLocator.getUser
  def removeUser(user: User) = userLocator.removeUser(user)


trait WithUserData 
  this: UserServiceComponent =>
  println(getUser)



object Main extends App 
  val userDataFake: WithUserData = new WithUserData with UserServiceComponent with UserTestRepositoryComponent
  val userDataReal: WithUserData = new WithUserData with UserServiceComponent with UserRealRepositoryComponent

或类似http://docs.scala-lang.org/tutorials/tour/implicit-parameters.html

【讨论】:

以上是关于创建测试范围/上下文以播种数据并运行应用程序,Scala Play Framework 2的主要内容,如果未能解决你的问题,请参考以下文章

创建一个 cron 以自动启动数据库播种器

播种时运行 sequelize 模型钩子

带有测试输出的 Lumen 5.1 播种

编辑并重新运行 Spring Boot 单元测试,无需重新加载上下文以加快测试速度

ASP.NET MVC Initializer 在更新数据库期间不会为数据库播种

实体框架在播种数据库上插入重复项[重复]