2016-03-03 69 views
1

我正在使用play 2.3.8,並在我的GlobalSettings中有一些基於應用程序模式進行更改的配置。所以,我有這樣的事情:播放2.3 FakeApplication模式未在測試中設置?

object Global extends GlobalSettings { 
    override def onLoadConfig(config: Configuration, path: java.io.File, classloader: ClassLoader, mode: Mode.Mode) = { 
     println(mode) 
     val customConfig = //Based on mode.* 
     config ++ configuration ++ Configuration(ConfigFactory.parseMap(customConfig)) 
    } 
} 

然後想寫測試,以確保這種行爲的工作原理:

class MyTest extends PlaySpec { 

    val testApp = FakeApplication(
     additionalConfiguration = Map(
      //SomeSettings And Stuff 
      "logger.application" -> "WARN", 
      "logger.root" -> "WARN" 
     ) 
    ) 

    val devApp = new FakeApplication(
     additionalConfiguration = Map(
      //SomeSettings And Stuff 
      "logger.application" -> "WARN", 
      "logger.root" -> "WARN" 
     ) 
    ) { 
     override val mode = Mode.Dev 
    } 

    val prodApp = new FakeApplication(
     additionalConfiguration = Map(
      //SomeSettings And Stuff 
      "logger.application" -> "WARN", 
      "logger.root" -> "WARN" 
     ) 
    ) { 
     override val mode = Mode.Prod 
    } 

    "ThisNonWorkingTestOfMine" must { 

     "when running application in test mode have config.thing = false" in running(testApp) { 
      assertResult(Mode.Test)(testApp.mode) 
      assertResult(false)(testApp.configuration.getBoolean("config.thing").get) 
     } 

     "when running application in dev mode have config.thing = false" in running(devApp) { 
      assertResult(Mode.Dev)(devApp.mode) 
      assertResult(false)(devApp.configuration.getBoolean("config.thing").get) 
     } 

     "when running application in prod mode have config.thing = true" in running(prodApp) { 
      assertResult(Mode.Prod)(prodApp.mode) 
      assertResult(true)(prodApp.configuration.getBoolean("config.thing").get) 
     } 
    } 

} 

當我運行這些測試中,我看到的東西有點古怪從我得心應手println

Test 
null 
null 
[info] MyTest: 
[info] ThisNonWorkingTestOfMine 
[info] play - Starting application default Akka system. 
[info] play - Shutdown application default Akka system. 
[info] - must when running application in test mode have config.thing = false 
[info] play - Application started (Dev) 
[info] - must when running application in dev mode have config.thing = false 
[info] play - Application started (Prod) 
[info] - must when running application in prod mode have config.thing = true *** FAILED *** 
[info] Expected true, but got false (MyTest.scala:64) 
[info] ScalaTest 

如何正確設置FakeApplication的模式播放2.3?我現在是基於從Mastering Play在頁面上,但顯然的方法是不使用的時候onLoadConfig似乎

編輯要走的路: 我也嘗試OneAppPerTest和創建在該FakeApplicationnewAppForTest方法,但它仍然表現怪異,null與上述方法類似。因爲讓我FakeApplication,然後嘗試在我Global對象從config.getString讀它,如果我在additionalConfiguration地圖設置像"foo" -> "bar"隨機屬性時,這是很奇怪的,它得到的記錄爲None,即使當我在測試它本身做app.configuration.getString顯示bar。感覺這裏有一些類型的斷開。而我,如果我用FakeApplication.apply方法,而不是new FakeApplication

回答

0

沒有得到空的模式,所以我覺得這事做the way that FakeApplication sets the mode to Mode.Test via override,因爲如果我複製FakeApplication類,並刪除該行並創建自己的版本讓我設置模式的課程我沒有問題。換句話說,在我的測試包,我宣佈了以下類:

package play.api.test 

import play.api.mvc._ 
import play.api.libs.json.JsValue 
import scala.concurrent.Future 
import xml.NodeSeq 
import play.core.Router 
import scala.runtime.AbstractPartialFunction 
import play.api.libs.Files.TemporaryFile 
import play.api.{ Application, WithDefaultConfiguration, WithDefaultGlobal, WithDefaultPlugins } 

case class FakeModeApplication(
    override val path: java.io.File = new java.io.File("."), 
    override val classloader: ClassLoader = classOf[FakeModeApplication].getClassLoader, 
    val additionalPlugins: Seq[String] = Nil, 
    val withoutPlugins: Seq[String] = Nil, 
    val additionalConfiguration: Map[String, _ <: Any] = Map.empty, 
    val withGlobal: Option[play.api.GlobalSettings] = None, 
    val withRoutes: PartialFunction[(String, String), Handler] = PartialFunction.empty, 
    val mode: play.api.Mode.Value 
) extends { 
    override val sources = None 
} with Application with WithDefaultConfiguration with WithDefaultGlobal with WithDefaultPlugins { 
    override def pluginClasses = { 
     additionalPlugins ++ super.pluginClasses.diff(withoutPlugins) 
    } 

    override def configuration = { 
     super.configuration ++ play.api.Configuration.from(additionalConfiguration) 
    } 

    override lazy val global = withGlobal.getOrElse(super.global) 

    override lazy val routes: Option[Router.Routes] = { 
     val parentRoutes = loadRoutes 
     Some(new Router.Routes() { 
      def documentation = parentRoutes.map(_.documentation).getOrElse(Nil) 
      // Use withRoutes first, then delegate to the parentRoutes if no route is defined 
      val routes = new AbstractPartialFunction[RequestHeader, Handler] { 
       override def applyOrElse[A <: RequestHeader, B >: Handler](rh: A, default: A => B) = 
        withRoutes.applyOrElse((rh.method, rh.path), (_: (String, String)) => default(rh)) 
       def isDefinedAt(rh: RequestHeader) = withRoutes.isDefinedAt((rh.method, rh.path)) 
      } orElse new AbstractPartialFunction[RequestHeader, Handler] { 
       override def applyOrElse[A <: RequestHeader, B >: Handler](rh: A, default: A => B) = 
        parentRoutes.map(_.routes.applyOrElse(rh, default)).getOrElse(default(rh)) 
       def isDefinedAt(x: RequestHeader) = parentRoutes.map(_.routes.isDefinedAt(x)).getOrElse(false) 
      } 
      def setPrefix(prefix: String) { 
       parentRoutes.foreach(_.setPrefix(prefix)) 
      } 
      def prefix = parentRoutes.map(_.prefix).getOrElse("") 
     }) 
    } 
} 

然後在我的測試,我可以使用它像這樣:

val devApp = new FakeModeApplication(
    additionalConfiguration = Map(
     //SomeSettings And Stuff 
     "logger.application" -> "WARN", 
     "logger.root" -> "WARN" 
    ), mode = Mode.Dev 
) 

然後將模式值來通過正如我將其設置爲而不是null

我張貼這是一個答案,因爲它確實解決我所面臨的問題,但我沒有的爲什麼使得像這樣一個FakeApplication當新關鍵字的理解:new FakeApplication() { override mode ... }導致模式在GlobalSettings上的onLoadConfig方法中爲null。這感覺就像一個黑客而不是一個解決方案,如果有足夠的知識的人可以發佈一個解決方案,包括不復制整個FakeApplication類並更改一行,那麼我會很感激。

相關問題