unit-testing - 在 play 2.0 scala 中在同一个 FakeApplication() 中运行多个测试

标签 unit-testing scala playframework-2.0 specs2

我正在尝试学习 Play scala 中的单元测试,但我遇到了一些问题。我正在尝试在我的模型层上运行多个测试,如下所示:

"User Model" should {
    "be created and retrieved by username" in {
        running(FakeApplication()) {
            val newUser = User(username = "weezybizzle",password = "password")
            User.save(newUser)
            User.findOneByUsername("weezybizzle") must beSome
        }
    }
    "another test" in {
        running(FakeApplication()) {
            // more tests involving adding and removing users
        }
    }
}

但是这样操作的时候,我在第二次单元测试中连接数据库失败,说连接关闭了。我试图通过将所有代码包含在一个在同一个假应用程序上运行的块中来解决这个问题,但这也不起作用。
  running(FakeApplication()) {
    "be created and retrieved by username" in {
        val newUser = User(username = "weezybizzle",password = "password")
        User.save(newUser)
        User.findOneByUsername("weezybizzle") must beSome
    }
    "another test" in {
        // more tests involving adding and removing users
    }
  }

最佳答案

specs2 测试默认并行执行,这可能会导致访问数据库出现问题,尤其是当您依赖先前测试提供的 db 内容时。因此,要强制进行顺序测试,您必须告诉 specs2 这样做:

class ModelSpec extends Specification with Logging {
  override def is = args(sequential = true) ^ super.is
...
}

对于一次完成的测试 FakeApplication您可以将整个测试包装在其中:
  running(FakeApp) {
    log.trace("Project tests.")
    val Some(project) = Project.findByName("test1")

    "Project" should {

      "be retrieved by name" in {
        project must beAnInstanceOf[Project]
        project.description must endWith("project")
      }

可以找到整个样本here .那是我在用 Play 测试 MongoDB 时第一次尝试处理问题!框架。

我从 salat 借用的第二种方法项目,顺便说一下,这是处理 MongoDB 的规范示例的一个很好的来源(尽管它不是 Play!框架应用程序)。你必须定义一个特征扩展 AroundScope ,您可以在应用程序实例中放置任何需要初始化的内容:
import org.specs2.mutable._
import org.specs2.execute.StandardResults

import play.api.mvc._
import play.api.mvc.Results
import play.api.test._
import play.api.test.Helpers._

trait FakeApp extends Around with org.specs2.specification.Scope {

  val appCfg = Map(
    "first.config.key" -> "a_value",
    "second.config.key" -> "another value"
  )

  object FakeApp extends FakeApplication(
      additionalPlugins = Seq("com.github.rajish.deadrope.DeadropePlugin"),
      additionalConfiguration = appCfg
    ) {
    // override val routes = Some(Routes)
  }

  def around[T <% org.specs2.execute.Result](test: => T) = running(FakeApp) {
    Logger.debug("Running test ==================================")
    test  // run tests inside a fake application
  }
}

编辑 2013-06-30:

当前版本specs2 around签名应该是:
def around[T : AsResult](test: => T): Result

编辑结束

然后可以像这样编写测试:
class SomeSpec extends Specification { sequential // according to @Eric comment

  "A test group" should {
    "pass some tests" in new FakeApp {
      1 must_== 1
    }

    "and these sub-tests too" in {
      "first subtest" in new FakeApp {
         success
      }
      "second subtest" in new FakeApp {
         failure
      }
    }
  }
}

可以在 here 中找到此类套件的完整样本。 .

最后一点:在启动套件之前清理测试数据库也很好:
  step {
    MongoConnection().dropDatabase("test_db")
  }

关于unit-testing - 在 play 2.0 scala 中在同一个 FakeApplication() 中运行多个测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12028218/

相关文章:

playframework - 将 play 作为 war 文件部署到 servlet 容器中,即使它大量使用 JPA?

intellij-idea - Junit 无法在 Play 中处理 SBT! Intellij 14 上的框架项目

javascript - 将 Play Framework 参数传递给 javascript

c# - 当前 JsonReader 项不是对象

Android 单元测试 - 如何在与应用程序相同的项目中运行测试?

scala - Play Framework 静态文件的 nginx 配置

Scala:从嵌套案例类到展平案例类

java - TestNG with IntelliJ IDEA : How to use the testng. IntelliJ IDEA 9 中的 xml 文件

angular - 在 Angular 中模拟 NgbModal

regex - 包含字母数字,但不匹配特定单词