在测试Play控制器时模拟ActionBuilder的服务

时间:2014-05-08 07:58:38

标签: scala unit-testing playframework

我最近创建了一个ActionBuilder,它根据请求本身发送的“授权”令牌在请求中插入用户。我已经能够通过使用将其分成特征(这是被测试的元素)的技术以及它唯一能够扩展该特征的对象来成功地对其进行单元测试。

trait AuthenticatedTrait extends ActionBuilder[AuthenticatedRequest] {
  this: TokenServiceComponent =>
  def invokeBlock[A](request: Request[A], block: (AuthenticatedRequest[A]) => Future[SimpleResult]) = {
  [...]
}

object Authenticated extends AuthenticatedTrait with DefaultTokenServiceComponent with DefaultUserServiceComponent with TokenRepositorySlickComponent with UserRepositorySlickComponent

我还创建了一个使用此Authenticated操作的控制器:

trait ProfileController extends Controller {
  def identity = Authenticated { implicit request =>
    Ok(request.user.email)
  }
}

object ProfileController extends ProfileController

手动测试此控制器似乎工作正常,但我想添加一些自动化测试。这就是问题开始的地方。

我想模仿ActionBuilder或它使用的服务,但是当Authenticated被集成为对象时,我看不到这样做的方法。

那么,你如何测试你的ActionBuilder - 使用控制器?

1 个答案:

答案 0 :(得分:1)

我最终做的是创建一对特征,将动作构建器作为一种可覆盖的方法。

trait Authenticated {
  def authenticate: ActionBuilder[AuthenticatedRequest] = AuthenticatedAction
}

trait AuthenticatedMock extends Authenticated {
  def user: User

  object AuthenticatedActionMock extends ActionBuilder[AuthenticatedRequest] {
    def invokeBlock[A](request: Request[A], block: (AuthenticatedRequest[A]) => Future[SimpleResult]) = {
      block(new AuthenticatedRequest(user, request))
    }
  }

  override def authenticate = AuthenticatedActionMock
}

然后,控制器会混合Authenticated并对其操作使用authenticate。为了测试,AuthenticatedActionMock混合在一起并提供了用户。