I'm using anorm for play framework and I have the following service class:
@javax.inject.Singleton
class ProductService @Inject() (dbApi: DBApi) {
private val DB = dbApi.database("default")
def save(product: Product) = {
DB.withConnection { implicit connection =>
....
}
}
}
Two issues here:
1) I do not wish to add the line private val DB = dbApi.database("default")
in each Service class. What is the best way to abstract this?
2) I would also like to have the datasource configurable so that I can pass test datasource when writing Integration tests
Test class:
import models.ProductService
import org.scalatestplus.play.{OneAppPerSuite, PlaySpec}
import play.api.db.Databases
class ProductSpec extends PlaySpec with OneAppPerSuite {
var productService: ProductService = app.injector.instanceOf(classOf[ProductService])
Databases.withDatabase(
driver = "com.mysql.jdbc.Driver",
url = "jdbc:mysql://localhost/playtest",
config = Map(
"user" -> "test",
"password" -> "demo"
)
) { database =>
import play.api.db.evolutions._
Evolutions.applyEvolutions(database)
"Product" should {
"be retrieved by Id" in {
val product = productService.get(23)
product.get.name must equal("mobile")
}
}
}
}
Any suggestions?
You can inject the database
object itself instead of a DBApi
. By the way, one of Guice best practices is to inject only direct dependencies . So, your example could be something like:
import play.api.db.Database
@Singleton
class ProductService @Inject() (database: Database) {
def save(product: Product) = {
database.withConnection { implicit connection =>
....
}
}
}
Of course, if you want to inject a specific database (instead of the "default"
one), you can just annotate the property like this:
import play.api.db.Database
import play.db.NamedDatabase
@Singleton
class ProductService @Inject() (@NamedDatabase("customers") database: Database) {
def save(product: Product) = {
database.withConnection { implicit connection =>
....
}
}
}
And, at your tests, you can just create the Database
as you want and manually inject it to your service. See more details about how to do it at the docs .
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.