I had the same struggle and came up with such a solution (using the second approach):
Create a context for using DAO:
trait BaseContext{ def dbName: String val dbConfig = DatabaseConfigProvider.get[JdbcProfile](dbName) val db = dbConfig.db val profile = dbConfig.driver val tables = new Tables { // this is generated by Schema Code Generator override val profile: JdbcProfile = dbConfig.driver } } @Singleton class AppContext extends BaseContext{ def dbName = "mysql" // name in your conf right after "slick.dbs" } @Singleton class TestingContext extends BaseContext{ def dbName = "h2" }
Then create a module to bind the injection and don't forget to include it in conf using play.modules.enabled += "your.Module" :
class ContextModule(environment: Environment, configuration: Configuration) extends AbstractModule { override def configure(): Unit = { if (configuration.getString("app.mode").contains("test")) { bind(classOf[BaseContext]) .to(classOf[TestingContext]) } else { bind(classOf[BaseContext]) .to(classOf[AppContext]) } } }
And add it to every DAO you create:
class SomeDAO @Inject()(context: BaseContext){ val dbConfig = context.dbConfig val db = context.db val tables = context.tables import tables.profile.api._ def otherStuff....
And the last step, your configuration file. In my case, I used app.mode to indicate the environment, and I use a separate .conf for another environment. The reason is that in this conf you must have the correct database configuration. Here's a sample:
app.mode = "test" # Database configuration slick.dbs = { # for unit test h2 { driver = "slick.driver.H2Driver$" db = { url = "jdbc:h2:mem:test;MODE=MYSQL" driver = "org.h2.Driver" keepAliveConnection = true } } }
I am sure that my solution is not elegant, but it delivers the goods. :) Any best solution is welcome!
source share