[英]Play Framework 2.5 Test ApplicationLifecycle Guice Specs2 setup
I am trying to run some functional tests with play2-reactivemongo
. 我正在尝试使用play2-reactivemongo
运行一些功能测试。 I will try to be as concrete as possible, but if something is missing please let me know. 我会尽量保持具体,但如果缺少某些内容,请告诉我。
My dependencies are here 我的依赖在这里
libraryDependencies ++= Seq(
cache,
"org.reactivemongo" %% "play2-reactivemongo" % "0.12.0",
"com.mohiva" %% "play-silhouette" % "4.0.0",
"com.mohiva" %% "play-silhouette-testkit" % "4.0.0" % "test",
specs2 % Test
)
In MongoUserDao.scala
在MongoUserDao.scala
import play.modules.reactivemongo._
import play.modules.reactivemongo.json._
import reactivemongo.play.json.collection.JSONCollection
class MongoUserDao @Inject() (val reactiveMongoApi: ReactiveMongoApi) extends UserDao {
val usersFuture = reactiveMongoApi.database.map(_.collection[JSONCollection]("users"))
...
}
In DaoSpecResources.scala
在DaoSpecResources.scala
trait DaoSpecResources {
val timeout = DurationInt(10).seconds
val fakeApp = new GuiceApplicationBuilder()
.in(Mode.Test)
.configure(
"play.modules.enabled" -> List("play.modules.reactivemongo.ReactiveMongoModule"),
"mongodb.uri" -> "mongodb://localhost:27017/test"
)
.build
val reactiveMongoApi = fakeApp.injector.instanceOf[ReactiveMongoApi]
...
}
When I try to run the test I get this error 当我尝试运行测试时,出现此错误
[error] cannot create an instance for class daos.UserDaoSpec
[error] caused by com.google.inject.CreationException: Unable to create injector, see the following errors:
[error]
[error] 1) No implementation for play.api.inject.ApplicationLifecycle was bound.
[error] while locating play.api.inject.ApplicationLifecycle
[error] for parameter 1 at services.ApplicationTimer.<init>(ApplicationTimer.scala:24)
[error] at Module.configure(Module.scala:23) (via modules: com.google.inject.util.Modules$OverrideModule -> Module)
[error]
[error] 1 error
This is caused by app/services/ApplicationTimer.scala
, which depends on ApplicationLifecycle
, but you haven't bound any implementation to ApplicationLifecycle
. 这是由app/services/ApplicationTimer.scala
引起的,它取决于ApplicationLifecycle
,但是您尚未将任何实现绑定到ApplicationLifecycle
。 ApplicationTimer
is a demo included in every new Play project. ApplicationTimer
是每个新的Play项目中包含的演示。 You should probably remove it completely if you don't need it, otherwise at least disable it if running in test mode. 如果不需要它,可能应该将其完全删除;否则,如果在测试模式下运行,则至少应将其禁用。 See disabling modules and overriding modules . 请参阅禁用模块和覆盖模块 。
However, since DefaultReactiveMongoApi
also depends on ApplicationLifecycle
, you'll need to provide a binding to an implementation of ApplicationLifecycle
. 但是,由于DefaultReactiveMongoApi
也依赖于ApplicationLifecycle
,因此您需要提供对ApplicationLifecycle
的实现的绑定。 The easiest way: 最简单的方法:
import play.api.inject.{ ApplicationLifecycle, DefaultApplicationLifecycle }
import play.api.inject.bind
trait DaoSpecResources {
val timeout = DurationInt(10).seconds
val fakeApp = new GuiceApplicationBuilder()
.in(Mode.Test)
.configure(
"play.modules.enabled" -> List("play.modules.reactivemongo.ReactiveMongoModule"),
"mongodb.uri" -> "mongodb://localhost:27017/test"
)
.bindings(bind[ApplicationLifecycle].to[DefaultApplicationLifecycle])
.build
val reactiveMongoApi = fakeApp.injector.instanceOf[ReactiveMongoApi]
val lifecycle = fakeApp.injector.instanceOf[DefaultApplicationLifecycle]
def stopApp = lifecycle.stop()
}
(added 5 lines: imports, bindings
, lifecycle
and stopApp
) (添加了5行:导入, bindings
, lifecycle
和stopApp
)
Then, in your test spec, add step(stopApp)
at the end, like so: 然后,在测试规范中,最后添加step(stopApp)
,如下所示:
class FooSpec extends PlaySpecification with DaoSpecResources {
// Your examples...
step(stopApp)
}
Personally, I'd create a specialized trait extending Specification
or PlaySpecification
which would set up and tear down everything automatically, like in this example from specs2 documentation . 就个人而言,我将创建一个特殊的特性来扩展Specification
或PlaySpecification
,这些特性将自动设置和PlaySpecification
所有内容, 例如specs2文档中的示例 。
trait PlayWithMongoSpecification extends PlaySpecification {
val timeout = DurationInt(10).seconds
val fakeApp = new GuiceApplicationBuilder()
.in(Mode.Test)
.configure(
"play.modules.enabled" -> List("play.modules.reactivemongo.ReactiveMongoModule"),
"mongodb.uri" -> "mongodb://localhost:27017/test"
)
.bindings(bind[ApplicationLifecycle].to[DefaultApplicationLifecycle])
.build
val reactiveMongoApi = fakeApp.injector.instanceOf[ReactiveMongoApi]
val lifecycle = fakeApp.injector.instanceOf[DefaultApplicationLifecycle]
def stopApp = lifecycle.stop()
override def map(fs: =>Fragments) = fs ^ step(stopApp)
}
class FooSpec extends PlayWithMongoSpecification {
// Your examples...
}
You may consider making reactiveMongoApi
a lazy val
. 您可以考虑将reactiveMongoApi
为lazy val
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.