Play 2.4.0 功能测试中的 Specs2/Guice 问题
Posted
技术标签:
【中文标题】Play 2.4.0 功能测试中的 Specs2/Guice 问题【英文标题】:Specs2/Guice issue in Play 2.4.0 functional tests 【发布时间】:2015-06-12 06:45:06 【问题描述】:我遇到了一个问题,即在测试之间明显存在依赖关系,这导致大多数测试失败。在每种情况下,调试都会显示在测试类中创建的第一个应用程序用于所有测试,这会导致失败。
我尝试添加isolated
和sequential
,但没有效果。
我是在做一些非常愚蠢或非常愚蠢的事情吗?
例如,这里是SubjectNotPresentTest.scala
class SubjectNotPresentTest extends AbstractViewTest
"show constrained content when subject is not present" in new WithApplication(testApp(handler()))
val html = subjectNotPresentContent(FakeRequest())
private val content: String = Helpers.contentAsString(html)
content must contain("This is before the constraint.")
content must contain("This is protected by the constraint.")
content must contain("This is after the constraint.")
"hide constrained content when subject is present" in new WithApplication(testApp(handler(subject = Some(user()))))
val user = new User("foo", Scala.asJava(List.empty), Scala.asJava(List.empty))
val html = subjectNotPresentContent(FakeRequest())
private val content: String = Helpers.contentAsString(html)
content must contain("This is before the constraint.")
content must not contain("This is protected by the constraint.")
content must contain("This is after the constraint.")
GuiceApplicationBuilder 用于parent class 用于创建应用程序进行测试。
val app = new GuiceApplicationBuilder()
.bindings(new DeadboltModule())
.bindings(bind[HandlerCache].toInstance(LightweightHandlerCache(handler)))
.overrides(bind[CacheApi].to[FakeCache])
.in(Mode.Test)
.build()
您可以在https://travis-ci.org/schaloner/deadbolt-2-scala/builds/66369307#L805查看失败示例
所有测试都可以在https://github.com/schaloner/deadbolt-2-scala/tree/master/code/test/be/objectify/deadbolt/scala/views找到
谢谢, 史蒂夫
【问题讨论】:
【参考方案1】:看起来问题是由于在有多个应用程序的测试环境中静态引用当前 Play 应用程序时引起的 - 即使它们在逻辑上是分开的。
由于无法将组件注入(据我所知)到模板中,我创建了一个helper object,它使用Play.current.injector
定义了几个val
s。
val viewSupport: ViewSupport = Play.current.injector.instanceOf[ViewSupport]
val handlers: HandlerCache = Play.current.injector.instanceOf[HandlerCache]
(TTBOMK,也不可能注入到对象中,否则我可以将组件注入到对象中,每个人都可以回家)。
更好的方法是将所需的内容作为隐式公开。
object ViewAccessPoint
private[deadbolt] val viewStuff = Application.instanceCache[ViewSupport]
private[deadbolt] val handlerStuff = Application.instanceCache[HandlerCache]
object Implicits
implicit def viewSupport(implicit application: Application): ViewSupport = viewStuff(application)
implicit def handlerCache(implicit application: Application): HandlerCache = handlerStuff(application)
在视图中,导入隐式就可以了。
@import be.objectify.deadbolt.scala.DeadboltHandler
@import be.objectify.deadbolt.scala.ViewAccessPoint.Implicits._
@import play.api.Play.current
@(handler: DeadboltHandler = handlerCache(current).apply(), name: String, meta: String = null, timeout: Function0[Long] = viewSupport.defaultTimeout)(body: => play.twirl.api.Html)(implicit request: Request[Any])
@if(viewSupport.dynamic(name, meta, handler, timeout(), request))
@body
【讨论】:
以上是关于Play 2.4.0 功能测试中的 Specs2/Guice 问题的主要内容,如果未能解决你的问题,请参考以下文章
使用 scala play specs2 针对测试 mysql 数据库的演变
排除 specs2 作为 sbt 中 play 框架的传递依赖
使用 Slick、specs2 和 Postgresql 进行 2.4 测试