使用Guice时如何设置我的模拟Dao类?

时间:2015-01-07 02:43:24

标签: 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 UserServiceImpl @Inject(val userDao: UserDao) extends UserService = {

  def getById(userId: Int): Option[User] = {
    getDb().withSession { implicit session =>
         return userDao.getById(userId)
    }
  }
}

使用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类连接了我的Guice。

我很困惑,我应该在哪里创建模拟对象(使用mockito),我应该如何使用Guice连接它们?在ServiceModule或?

我的设计似乎有误,因为我的BaseService与数据库有连接,我需要以某种方式重构它。

寻找一种摆脱这种糟糕设计的方法,我现在似乎有想法?

1 个答案:

答案 0 :(得分:0)

您可以将数据库连接移动到DAO层。您的应用程序应该有三层:controller - >服务 - > DAO。所有服务层需要知道的是DAO提供的功能,即CRUD操作;它不应该知道有关数据库连接的任何信息,因为这是DAO的责任。

我不太确定Slick框架,但对于带Guice的Play框架,它允许禁用" real"在应用程序运行时您期望的绑定(注入依赖项)并启用仅用于此类测试的绑定:

implicit override lazy val app = new GuiceApplicationBuilder()
  .configure(appConfig)
  .disable(classOf[ReactiveMongoModule], classOf[CommonModule])
  .bindings(bind(classOf[ReactiveMongoApi]).toInstance(api))
  .bindings(TestDaoModule())
  .build()

这是一个完整的集成测试(控制器层),希望它有所帮助:https://github.com/luongbalinh/play-mongo/blob/master/test/controllers/UserControllerTest.scala