我正在使用play 2.3.8并在我的GlobalSettings中进行一些根据应用程序模式进行更改的配置。所以我有这样的事情:
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
如何在Play 2.3中正确设置FakeApplication的模式?我现在拥有它的方式是基于Mastering Play的页面,但显然使用onLoadConfig的方式似乎不是
修改:
我还尝试使用OneAppPerTest
并在FakeApplication
方法中创建newAppForTest
,但它仍然表现得很奇怪,其中的null就像上面的方法一样。这真的很奇怪,因为如果我在制作"foo" -> "bar"
时在additionalConfiguration
地图中设置FakeApplication
等随机属性,然后尝试在config.getString
中读取Global
对象,它被记录为None
,即使我在测试本身app.configuration.getString
显示bar
。感觉这里存在某种类型的脱节。如果我使用FakeApplication.apply
方法而不是new FakeApplication
答案 0 :(得分: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时,我并不理解为什么新关键字:{ {1}}导致模式在GlobalSettings上的new FakeApplication() { override mode ... }
方法中为null。这感觉就像是一个黑客而不是解决方案,如果有足够知识的人可以发布一个不涉及复制完整的FakeApplication类并更改一行的解决方案,我会很感激。