Проблема Specs2/Guice в функциональных тестах Play 2.4.0

У меня проблема с зависимостями, которые, по-видимому, истекают кровью между тестами, что приводит к сбою большинства тестов. В каждом случае отладка показывает, что первое приложение, созданное в тестовом классе, используется для всех тестов, и это приводит к сбоям.

Я пробовал добавлять 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 используется в родительский класс используется для создания приложения для тестирования.

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

Спасибо, Стив


person Steve Chaloner    schedule 12.06.2015    source источник


Ответы (1)


Похоже, проблема возникает, когда на текущее приложение Play статически ссылаются в тестовой среде, в которой есть несколько приложений, даже если они логически разделены.

Поскольку компоненты не могут быть внедрены (насколько мне известно) в шаблоны, я создал вспомогательный объект, который использует Play.current.injector для определения пары val.

  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
}
person Steve Chaloner    schedule 14.06.2015