Play Framework 2.4.1:play.application.loader 设置在测试模式下被忽略
Play Framework 2.4.1: play.application.loader setting ignored in Test mode
我想为每种模式(开发、生产、测试)加载不同的配置文件,所以我写了以下内容。
class CustomApplicationLoader extends GuiceApplicationLoader {
override protected def builder(context: Context): GuiceApplicationBuilder = {
Logger.info("CUSTOMBUILDER")
val builder = initialBuilder.in(context.environment).overrides(overrides(context): _*)
val mode = context.environment.mode
val configFile = s"application.${mode.toString.toLowerCase}.conf"
Logger.info("Using config file: %s".format(configFile))
val config = Configuration(ConfigFactory.load(configFile))
builder.loadConfig(config ++ context.initialConfiguration)
}
}
在我的 application.conf 文件中
play.application.loader = "modules.CustomApplicationLoader"
这在 Prod 和 Dev 模式下完美运行,但在测试模式下运行不佳。在测试模式下,Logger.info("CUSTOMBUILDER") 永远不会被触发。
我似乎无法在文档中找到任何关于为什么这在测试模式下不起作用的信息。如果您能帮助我们在测试模式下工作或确定问题的根源,我们将不胜感激。
弄清楚了,希望这能帮助到别人。
作为 play2.4 和 specs2 的新手,我没有意识到默认情况下的测试 运行 没有任何应用程序上下文。但是我注意到,当 运行 和 in new WithApplication
时,它们是使用默认的 applicationloader 加载的。
我的问题的快速解决方法是使用非常相似的 WithApplicationLoader
代替:
in new WithApplicationLoader(new CustomApplicationLoader)
我最终编写了一个将它们捆绑在一起的自定义上下文提供程序,因为我认为它更简洁:
object TestHelpers {
val customApplicationLoader = new CustomApplicationLoader
val customContext = ApplicationLoader.createContext(new Environment(new java.io.File("."), ApplicationLoader.getClass.getClassLoader, Mode.Test))
abstract class WithCustomApp(applicationLoader: ApplicationLoader = customApplicationLoader, context: ApplicationLoader.Context = customContext) extends Around with Scope {
implicit lazy val app = applicationLoader.load(context)
def around[T: AsResult](t: => T): Result = {
Helpers.running(app)(AsResult.effectively(t))
}
}
}
这是一个使用示例:
"Status" should {
"receive an ok" in new WithCustomApp {
val car1 = route(FakeRequest(GET, "/status")).get
status(car1) must equalTo(OK)
val body = contentAsString(car1)
body mustEqual "ok"
}
}
如我所愿,这正确地加载了 application.test.conf
。这对于任何特定于测试的配置都非常有用,并且对于为测试(h2:在内存中)和开发(jdbc:mysql)进行单独的数据库配置非常方便。
我想为每种模式(开发、生产、测试)加载不同的配置文件,所以我写了以下内容。
class CustomApplicationLoader extends GuiceApplicationLoader {
override protected def builder(context: Context): GuiceApplicationBuilder = {
Logger.info("CUSTOMBUILDER")
val builder = initialBuilder.in(context.environment).overrides(overrides(context): _*)
val mode = context.environment.mode
val configFile = s"application.${mode.toString.toLowerCase}.conf"
Logger.info("Using config file: %s".format(configFile))
val config = Configuration(ConfigFactory.load(configFile))
builder.loadConfig(config ++ context.initialConfiguration)
}
}
在我的 application.conf 文件中
play.application.loader = "modules.CustomApplicationLoader"
这在 Prod 和 Dev 模式下完美运行,但在测试模式下运行不佳。在测试模式下,Logger.info("CUSTOMBUILDER") 永远不会被触发。
我似乎无法在文档中找到任何关于为什么这在测试模式下不起作用的信息。如果您能帮助我们在测试模式下工作或确定问题的根源,我们将不胜感激。
弄清楚了,希望这能帮助到别人。
作为 play2.4 和 specs2 的新手,我没有意识到默认情况下的测试 运行 没有任何应用程序上下文。但是我注意到,当 运行 和 in new WithApplication
时,它们是使用默认的 applicationloader 加载的。
我的问题的快速解决方法是使用非常相似的 WithApplicationLoader
代替:
in new WithApplicationLoader(new CustomApplicationLoader)
我最终编写了一个将它们捆绑在一起的自定义上下文提供程序,因为我认为它更简洁:
object TestHelpers {
val customApplicationLoader = new CustomApplicationLoader
val customContext = ApplicationLoader.createContext(new Environment(new java.io.File("."), ApplicationLoader.getClass.getClassLoader, Mode.Test))
abstract class WithCustomApp(applicationLoader: ApplicationLoader = customApplicationLoader, context: ApplicationLoader.Context = customContext) extends Around with Scope {
implicit lazy val app = applicationLoader.load(context)
def around[T: AsResult](t: => T): Result = {
Helpers.running(app)(AsResult.effectively(t))
}
}
}
这是一个使用示例:
"Status" should {
"receive an ok" in new WithCustomApp {
val car1 = route(FakeRequest(GET, "/status")).get
status(car1) must equalTo(OK)
val body = contentAsString(car1)
body mustEqual "ok"
}
}
如我所愿,这正确地加载了 application.test.conf
。这对于任何特定于测试的配置都非常有用,并且对于为测试(h2:在内存中)和开发(jdbc:mysql)进行单独的数据库配置非常方便。