首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用扩展控制器的Play 2.4 macwire示例看起来不像是可以嘲笑的

使用扩展控制器的Play 2.4 macwire示例看起来不像是可以嘲笑的
EN

Stack Overflow用户
提问于 2016-03-21 00:22:31
回答 2查看 302关注 0票数 1

我采用了现有的macwire示例,并像这样扩展了控制器CoffeeController.scala。

代码语言:javascript
复制
package com.softwaremill.play24.controllers

import com.softwaremill.play24.dao.CoffeeDao
import play.api.i18n.Lang
import play.api.libs.json.Json
import play.api.mvc._

import scala.concurrent.{Future}
import play.api.libs.concurrent.Execution.Implicits.defaultContext
import play.api.mvc.Results._

class CoffeeController(
  coffeeDao: CoffeeDao
)(implicit ec: SomeContextBuilder) extends AnotherController {

  def fetchAll() = DecoratedAction() { request =>
    coffeeDao.all.map { coffees =>
      Ok(Json.toJson(coffees))
    }
  }

  def priced(price: Double) = ResolvedDecoratedAction() { request =>
    coffeeDao.byPriceWithSuppliers(price).map { result =>
      Ok(Json.toJson(result.toMap))
    }
  }
}

trait ContextBuilder[U <: TraitLike] {
  def build(request: Request[AnyContent]): Future[Either[Result, RequestWithContext[U]]]
  def buildAuthenticated(request: Request[AnyContent]): Future[Either[Result, RequestWithResolvedContext[U]]]
}

trait TraitLike {
  def id: String
}

trait WithSessionId {
  self: RequestHeader =>
  lazy val sessionId = self.session.get("auth").getOrElse(java.util.UUID.randomUUID().toString)
}

case class RequestWithContext[U <: TraitLike](request: Request[AnyContent], lang: Lang, anything: Option[U]) extends WrappedRequest(request) with WithSessionId
case class RequestWithResolvedContext[U <: TraitLike](request: Request[AnyContent], lang: Lang, anything: U, rememberMe: Boolean = false) extends WrappedRequest(request) with WithSessionId
case class Trait(val id: String) extends TraitLike

class AnotherController[U <: TraitLike](implicit ctxBuilder: ContextBuilder[U]) extends Controller  {
  def DecoratedAction(bodyParser: BodyParser[AnyContent] = parse.anyContent)(f: RequestWithContext[U] => Future[Result]) = Action.async {
    implicit request =>
      ctxBuilder.build(request) flatMap {
        case Left(r) =>
          Future.successful(r)
        case Right(requestContext) =>
          f(requestContext).map(_.addingToSession( ("auth" , requestContext.sessionId) ))
      }
  }

  def ResolvedDecoratedAction(bodyParser: BodyParser[AnyContent] = parse.anyContent)(f: RequestWithResolvedContext[U] => Future[Result]) = Action.async {
    implicit request =>
      ctxBuilder.buildAuthenticated(request) flatMap {
        case Left(r) =>
          Future.successful(r)
        case Right(requestContext) =>
          f(requestContext).map(_.addingToSession( ("auth", requestContext.sessionId) ))
      }
  }
}

class SomeContextBuilder extends ContextBuilder[TraitLike] {
  override def build(request: Request[AnyContent]): Future[Either[Result, RequestWithContext[TraitLike]]] = Future.successful(Right(RequestWithContext(request, Lang("en-us"),None)))

  override def buildAuthenticated(request: Request[AnyContent]): Future[Either[Result, RequestWithResolvedContext[TraitLike]]] = Future.successful(Right(RequestWithResolvedContext(request, Lang("en-us"),Trait("id"),false)))
}

ControllerModule.scala

代码语言:javascript
复制
package com.softwaremill.play24.modules

import com.softwaremill.macwire._
import com.softwaremill.play24.controllers.{SomeContextBuilder, SupplierController, CoffeeController}
import com.softwaremill.play24.dao.{CoffeeDao, SupplierDao}
import play.api.libs.ws.WSClient

import scala.concurrent.ExecutionContext

trait ControllerModule {

  // Dependencies
  implicit def ec: ExecutionContext
  implicit val ctxBuilder = wire[SomeContextBuilder]
  def wsClient: WSClient
  def supplierDao: SupplierDao
  def coffeeDao: CoffeeDao

  // Controllers
  lazy val supplierController = wire[SupplierController]
  lazy val coffeeController = wire[CoffeeController]
}

然而,当我运行测试时,我得到了一个堆栈跟踪:

代码语言:javascript
复制
[error]   ! return priced by coffee, supplier
  [error]    No configuration setting found for key 'play.crypto.secret' (SimpleConfig.java:152)
[error] com.typesafe.config.impl.SimpleConfig.findKeyOrNull(SimpleConfig.java:152)
[error] com.typesafe.config.impl.SimpleConfig.findOrNull(SimpleConfig.java:170)
[error] com.typesafe.config.impl.SimpleConfig.findOrNull(SimpleConfig.java:176)
[error] com.typesafe.config.impl.SimpleConfig.findOrNull(SimpleConfig.java:176)
[error] com.typesafe.config.impl.SimpleConfig.findOrNull(SimpleConfig.java:193)
[error] com.typesafe.config.impl.SimpleConfig.findOrNull(SimpleConfig.java:198)
[error] com.typesafe.config.impl.SimpleConfig.getIsNull(SimpleConfig.java:208)
[error] play.api.PlayConfig.getOptional(Configuration.scala:951)
[error] play.api.PlayConfig.getOptionalDeprecated(Configuration.scala:996)
[error] play.api.libs.CryptoConfigParser.get$lzycompute(Crypto.scala:232)
[error] play.api.libs.CryptoConfigParser.get(Crypto.scala:203)
[error] play.api.libs.Crypto$$anonfun$crypto$1.apply(Crypto.scala:42)
[error] play.api.libs.Crypto$$anonfun$crypto$1.apply(Crypto.scala:40)
[error] play.api.libs.Crypto$.crypto(Crypto.scala:43)
[error] play.api.libs.Crypto$.sign(Crypto.scala:67)
[error] play.api.mvc.CookieBaker$class.encode(Http.scala:502)
[error] play.api.mvc.Session$.encode(Http.scala:651)
[error] play.api.mvc.CookieBaker$class.encodeAsCookie(Http.scala:554)
[error] play.api.mvc.Session$.encodeAsCookie(Http.scala:651)
[error] play.api.mvc.Result.withSession(Results.scala:170)
[error] play.api.mvc.Result.addingToSession(Results.scala:262)
[error] com.softwaremill.play24.controllers.AnotherController$$anonfun$ResolvedDecoratedAction$1$$anonfun$apply$5$$anonfun$apply$6.apply(CoffeeController.scala:64)
[error] com.softwaremill.play24.controllers.AnotherController$$anonfun$ResolvedDecoratedAction$1$$anonfun$apply$5$$anonfun$apply$6.apply(CoffeeController.scala:64)

我可以尝试运行(FakeApplication()){...},但是我得到了路由注入器错误。目前代码在build.sbt中使用routesGenerator := InjectedRoutesGenerator,但我不认为它会转换到测试阶段。

我已经把代码放在这里了https://github.com/tashiscool/Play24MacwireMockingFailure

如果您运行激活器测试,您应该在控制器测试中看到错误。

EN

回答 2

Stack Overflow用户

发布于 2016-03-22 23:45:09

我遇到了完全相同的问题。我花了一点时间来研究它,似乎通过FakeRequest#withSession,你可以在play中调用Crypto库的一些部分,这些部分依赖于配置,但无法传递FakeApplication

...but我确实找到了一个简单的解决方法,可能也适用于您。基本上,只是用mockito spy包装FakeRequest,然后截断试图调用内部Crypto API的方法。

代码语言:javascript
复制
import org.mockito.Mockito.{doReturn, spy}
import play.api.mvc.{AnyContentAsEmpty, Session}
import play.api.test.FakeRequest

trait AuthSupport { 

  def fakeRequest(): FakeRequest[AnyContentAsEmpty.type] = {
    val request = spy(FakeRequest())
    doReturn(Session(Map("userId" -> "1"))).when(request).session
    request
  }

}
票数 1
EN

Stack Overflow用户

发布于 2016-03-22 01:19:29

看起来你没有在application.conf中配置play secret

你能试着给它下定义吗?

请在此处查找更多details

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36116289

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档