I think the key problem is that val in Scala traits are initialized during the build that precedes the launch of the Play test application (presumably its life cycle is tied to each sample example). You have a couple of workarounds:
- do everything in
DbConfigWeb a def or maybe lazy val - give
DbConfigWeb abstract field play.api.Application from which the configuration values ββare extracted (not using current ) and pass it explicitly (fake application) to any DbManagementWeb as a constructor parameter
Here's a simplified version using the first approach (which works for me):
import play.api.Play.current trait DbConfig trait DbConfigWeb extends DbConfig { self: DbQualifier => // Using defs instead of vals def url: String = current.configuration.getString(qualifier + ".url").get def username: String = current.configuration.getString(qualifier + ".user").get def password: String = current.configuration.getString(qualifier + ".password").get def driver: String = current.configuration.getString(qualifier + ".driver").get } trait DbQualifier { val qualifier: String } trait DbTestQualifier extends DbQualifier { override val qualifier = "db.test" }
and spec:
import controllers.{DbConfigWeb, DbTestQualifier} import org.scalatestplus.play.{OneAppPerSuite, PlaySpec} import play.api.test.FakeApplication class DbConfigTest extends PlaySpec with OneAppPerSuite { implicit override lazy val app: FakeApplication = FakeApplication( additionalConfiguration = Map("db.test.url" -> "jdbc:h2:mem:play", "db.test.user" -> "sa", "db.test.password" -> "", "db.test.driver" -> "org.h2.Driver")) val dbManagementWeb = new DbConfigWeb with DbTestQualifier "DbConfigWebTest" must { "have the same username as what is defined in application.conf" in { dbManagementWeb.username must be("sa") } } }
Personally, I prefer the second approach, which saves the state of the application explicitly, rather than relying on play.api.Play.current , which you cannot rely on always running.
You mentioned in the comments that lazy val did not work for you, but I can only assume that some chain of calls made you initialize: check again that this is not so.
Please also note that the initialization order for val can be complicated, and although some may disagree, it is a pretty safe bet to stick with def as members of an element if you are not sure about its expensive operation (in this case lazy val may be an option.)
source share