Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Play Framework 2.4.1: play.application.loader setting ignored in Test mode

I want to load different config files for each mode (Dev, Prod, Test) so I wrote the following.

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)

    }
}

In my application.conf file I have

play.application.loader = "modules.CustomApplicationLoader"

This works perfectly in Prod and Dev modes, but not in Test mode. In Test mode the Logger.info("CUSTOMBUILDER") is never triggered.

I can't seem to find anything in the documentation with regards to why this would not work in Test mode. Any help in getting this to work in Test mode or determining the source of the issue would be greatly appreciated.

like image 939
alav Avatar asked Oct 23 '25 21:10

alav


1 Answers

Figured it out, hopefully this helps someone out.

Being fairly new to play2.4 and specs2 I did not realize that tests by default are run without any application context. I noticed however, that when run with in new WithApplication they are loaded using the default applicationloader.

A quick fix to my problem was to use the very similar WithApplicationLoader instead:

in new WithApplicationLoader(new CustomApplicationLoader)

I ended up writing a custom context provider that bundled that together because I thought it was a little cleaner:

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))
    }
  }
}

Here is an example of it in use:

"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"
  }
}

This correctly loads application.test.conf as I had hoped. This is great for any test specific configuration and really handy for having seperate db configurations for test (h2:in memory) and dev (jdbc:mysql).

like image 136
alav Avatar answered Oct 25 '25 17:10

alav



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!