我正在尝试学习 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!框架应用程序)。你必须定义一个特征扩展
Around
和 Scope
,您可以在应用程序实例中放置任何需要初始化的内容: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/