2016-03-20 46 views
1

我把現有macwire示例和擴展像這樣 CoffeeController.scala播放具有擴展控制器2.4 macwire例如似乎不喜歡的話可以被模擬

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

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] 
} 
控制器

然而,當我跑我得到一個堆棧跟蹤測試:

[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

如果您運行激活測試,你應該看到在控制器測試中的錯誤。

回答

0

看起來你沒有在application.conf中配置玩祕密
你可以嘗試並定義它嗎?

在這裏尋找更多details

+0

我已經試過了(即使它推到github上),但它並沒有任何區別:( – user2928738

+0

好這個問題似乎是與'play.crypto.secret'設置,不與macwire或嘲諷 – adamw

1

我遇到了相同問題。我花了一點時間研究它,看起來通過FakeRequest#withSession,你可以最終調用Crypto庫中的某些部分,這取決於配置,但無法通過FakeApplication

...但我找到了一個簡單的解決方法,可能也適合你。基本上只是用一個mockito間諜包裝FakeRequest,然後根據內部的Crypto API調用方法。

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 
    } 

} 
相關問題