2017-02-26 5 views
1

Ich entwickle Web-App mit Scala, Play Framework. Und ich muss Controller mit der benutzerdefinierten Aktion testen. Bitte, schauen Sie auf den Code:Mock funktionales Argument der Funktion

package controllers.helpers 

import play.api.mvc.{ActionBuilder, Request, Result} 

import scala.concurrent.Future 

class CustomAction extends ActionBuilder[Request] { 

    override def invokeBlock[A](request: Request[A], block: (Request[A]) => Future[Result]): Future[Result] = { 
    // do some stuff 
    block(request) 
    } 
} 


package controllers 

import javax.inject.Singleton 

import play.api.mvc.Controller 

@Singleton 
class SomeController @Inject() (customAction: CustomAction 
          ) extends Controller { 

    def foo() = customAction(parse.json) { implicit request => 
    // do some stuff and create result 
    } 
} 

Und unten finden Sie einen Code der Testklasse. Ich benutze Specs2 und ich habe org.mockito.exceptions.misusing.InvalidUseOfMatchersException auf der Linie mit customeActionMock.invokeBlock(any[Request[_]], any[(Request[_]) => Future[Result]]) returns mock[Future[Result]]

package controllers 
import controllers.helpers.CustomAction 
import org.specs2.mock.Mockito 
import play.api.mvc.{Request, Result} 
import play.api.test.{FakeHeaders, FakeRequest, PlaySpecification} 

import scala.concurrent.Future 

class SomeControllerSpec extends PlaySpecification with Mockito { 
    private val customeActionMock = mock[CustomAction] 
    customeActionMock.invokeBlock(any[Request[_]], any[(Request[_]) => Future[Result]]) returns mock[Future[Result]] //this doesn't work, exception is thrown there 


    "SomController" should { 
    "respond Ok on valid request" in { 
     val result = new UserController(customeActionMock).foo()(FakeRequest()) 
     status(result) shouldEqual OK 
    } 
    } 
} 

Ich verstehe, dass ich block Parameter des CustomAction falsch verspotten. Kann mir jemand helfen, es richtig zu machen?

+0

Die Art und Weise der Einrichtung Ihres Test würde der Wert 'result' des verspottete Wert' mock [Zukunft [Ergebnis]] halten '. Anders ausgedrückt, wenn Sie den Code verspotten, der den 'Block' ausführen soll, wird der Code in Ihrer Aktion nicht ausgeführt. Ich denke, ich würde' CustomAction' nicht mockern, sondern ihn Teil des Tests machen. – rethab

Antwort

0

Sie das Custom nicht spotten:

class SomeControllerSpec extends PlaySpecification with Mockito { 
    private val customeActionMock = new CustomAction 


    "SomController" should { 
    "respond Ok on valid request" in { 
     val result = new UserController(customeActionMock).foo()(FakeRequest()) 
     status(result) shouldEqual OK 
    } 
    } 
} 
1

Mein Projekt verwendet Wiedergabe 2.5.x. Ich benutze Scalatest. So teste ich Controller.

import org.scalatestplus.play.OneAppPerSuite 
import org.scalatest._ 
import org.scalatest.time.{Millis, Seconds, Span} 
import org.scalatest.concurrent.ScalaFutures 
import scala.concurrent.Future 

class SomeControllerSpec extends FlatSpec with Matchers with ScalaFutures with OneAppPerSuite { 
private val customeActionMock = new CustomAction // create an instance of a class 
implicit val defaultPatience = PatienceConfig(timeout = Span(5,Seconds), interval = Span(500, Millis)) 

it should "respond Ok on valid request" in { 
    val resultF : Future[Result] = new UserController(customeActionMock).foo()(FakeRequest()) 
    whenReady(resultF) { resultR => 
     resultR.header.status shouldBe 200 
    } 
    } 
} 
+0

Ich benutze 2.6 mit Play-Cache aktiviert. Ich verbringe 3 Stunden damit, diese Implementierung zu verspotten. Ich habe am Ende eine eigene Caching-Klasse für Tests erstellt, weil ich den gleichen Fehler hatte. Daumen runter für Play2. Danke @ecamur. –

Verwandte Themen