Scala 如何在使用Guice时设置模拟Dao类?
典型的服务如下所示:Scala 如何在使用Guice时设置模拟Dao类?,scala,playframework,guice,scalatest,Scala,Playframework,Guice,Scalatest,典型的服务如下所示: trait BaseService extends LazyLogging { def getDb() = { DatabaseHelper.getDb // database for the scala slick library } } abstract class UserService extends BaseService { def getById(userId: Int): Option[User] } class Us
trait BaseService extends LazyLogging {
def getDb() = {
DatabaseHelper.getDb // database for the scala slick library
}
}
abstract class UserService extends BaseService {
def getById(userId: Int): Option[User]
}
class UserServiceImpl @Inject(val userDao: UserDao) extends UserService = {
def getById(userId: Int): Option[User] = {
getDb().withSession { implicit session =>
return userDao.getById(userId)
}
}
}
implicit override lazy val app = new GuiceApplicationBuilder()
.configure(appConfig)
.disable(classOf[ReactiveMongoModule], classOf[CommonModule])
.bindings(bind(classOf[ReactiveMongoApi]).toInstance(api))
.bindings(TestDaoModule())
.build()
我使用Guice连接对象,如:
class ServiceModule extends ScalaModule {
def configure() {
bind[UserDao].to[UserDaoImpl]
bind[UserService].to[UserServiceImpl]
}
}
现在,当我使用scalatest进行单元测试时,我有点困惑如何将数据库访问解耦,因为我想模拟数据库响应
我的规格看起来像:
class UserServiceSpec extends UnitSpec with MockitoSugar {
val userService = injector.getInstance(classOf[UserService])
describe("UserServiceSpec") {
it("should do someting") {
val abc = userService.doSomething();
abc.name should be("abc")
}
}
}
我的UnitSpec类连接我的GUI
我很困惑,我应该在哪里创建模拟对象(使用mockito)以及如何使用Guice连接它们?在服务模块中还是
我的设计似乎是错误的,因为我的BaseService与数据库有连接,我需要以某种方式重构它
正在寻找一种方法来摆脱我目前看起来很糟糕的设计,想法?您可以将db连接移动到DAO层。应用程序应该有三层:控制器->服务->DAO。服务层需要知道的全部是DAO提供的功能,即CRUD操作;它不应该知道任何关于db连接的事情,因为这是DAO的责任 我对Slick framework不是很确定,但对于使用Guice的Play framework,它允许禁用应用程序运行时预期的“真实”绑定(注入的依赖项),并启用仅用于以下测试的绑定:
trait BaseService extends LazyLogging {
def getDb() = {
DatabaseHelper.getDb // database for the scala slick library
}
}
abstract class UserService extends BaseService {
def getById(userId: Int): Option[User]
}
class UserServiceImpl @Inject(val userDao: UserDao) extends UserService = {
def getById(userId: Int): Option[User] = {
getDb().withSession { implicit session =>
return userDao.getById(userId)
}
}
}
implicit override lazy val app = new GuiceApplicationBuilder()
.configure(appConfig)
.disable(classOf[ReactiveMongoModule], classOf[CommonModule])
.bindings(bind(classOf[ReactiveMongoApi]).toInstance(api))
.bindings(TestDaoModule())
.build()
这是一个完整的集成测试(控制器层),希望对您有所帮助:我不知道guice+scala,但对于Java,您可以使用Modules.override()添加一个将UserDao绑定到模拟(UserDao)实例的模块。您能在单元测试中完全避免使用guice吗?“我会这么做的。”塔维安巴恩斯说,“可能吧,我没想过。”。还有一个问题是,我的数据库池位于基本服务中,我需要以某种方式解决。