!htk change return type of TestResponse.fail to Unit to avoid surprises for Java implementors
This commit is contained in:
parent
560785eaaa
commit
44ed8afd49
4 changed files with 39 additions and 13 deletions
|
|
@ -7,19 +7,20 @@ package akka.http.javadsl.testkit
|
||||||
import akka.actor.ActorSystem
|
import akka.actor.ActorSystem
|
||||||
import akka.http.javadsl.server._
|
import akka.http.javadsl.server._
|
||||||
import akka.http.scaladsl.model.HttpResponse
|
import akka.http.scaladsl.model.HttpResponse
|
||||||
import akka.stream.ActorMaterializer
|
import akka.stream.{ Materializer, ActorMaterializer }
|
||||||
import org.junit.rules.ExternalResource
|
import org.junit.rules.ExternalResource
|
||||||
import org.junit.{ Assert, Rule }
|
import org.junit.{ Assert, Rule }
|
||||||
|
|
||||||
import scala.concurrent.duration._
|
import scala.concurrent.duration._
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A RouteTest that uses JUnit assertions.
|
* A RouteTest that uses JUnit assertions. ActorSystem and Materializer are provided as an [[ExternalResource]]
|
||||||
|
* and their lifetime is automatically managed.
|
||||||
*/
|
*/
|
||||||
abstract class JUnitRouteTestBase extends RouteTest {
|
abstract class JUnitRouteTestBase extends RouteTest {
|
||||||
protected def systemResource: ActorSystemResource
|
protected def systemResource: ActorSystemResource
|
||||||
implicit def system: ActorSystem = systemResource.system
|
implicit def system: ActorSystem = systemResource.system
|
||||||
implicit def materializer: ActorMaterializer = systemResource.materializer
|
implicit def materializer: Materializer = systemResource.materializer
|
||||||
|
|
||||||
protected def createTestResponse(response: HttpResponse): TestResponse =
|
protected def createTestResponse(response: HttpResponse): TestResponse =
|
||||||
new TestResponse(response, awaitDuration)(system.dispatcher, materializer) {
|
new TestResponse(response, awaitDuration)(system.dispatcher, materializer) {
|
||||||
|
|
@ -32,7 +33,7 @@ abstract class JUnitRouteTestBase extends RouteTest {
|
||||||
protected def assertTrue(predicate: Boolean, message: String): Unit =
|
protected def assertTrue(predicate: Boolean, message: String): Unit =
|
||||||
Assert.assertTrue(message, predicate)
|
Assert.assertTrue(message, predicate)
|
||||||
|
|
||||||
protected def fail(message: String): Nothing = {
|
protected def fail(message: String): Unit = {
|
||||||
Assert.fail(message)
|
Assert.fail(message)
|
||||||
throw new IllegalStateException("Assertion should have failed")
|
throw new IllegalStateException("Assertion should have failed")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ package akka.http.javadsl.testkit
|
||||||
import scala.annotation.varargs
|
import scala.annotation.varargs
|
||||||
import scala.concurrent.ExecutionContext
|
import scala.concurrent.ExecutionContext
|
||||||
import scala.concurrent.duration._
|
import scala.concurrent.duration._
|
||||||
import akka.stream.ActorMaterializer
|
import akka.stream.Materializer
|
||||||
import akka.http.scaladsl.server
|
import akka.http.scaladsl.server
|
||||||
import akka.http.javadsl.model.HttpRequest
|
import akka.http.javadsl.model.HttpRequest
|
||||||
import akka.http.javadsl.server.{ HttpApp, AllDirectives, Route, Directives }
|
import akka.http.javadsl.server.{ HttpApp, AllDirectives, Route, Directives }
|
||||||
|
|
@ -19,9 +19,17 @@ import akka.actor.ActorSystem
|
||||||
import akka.event.NoLogging
|
import akka.event.NoLogging
|
||||||
import akka.http.impl.util._
|
import akka.http.impl.util._
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A base class to create route tests for testing libraries. An implementation needs to provide
|
||||||
|
* code to provide and shutdown an [[ActorSystem]], [[Materializer]], and [[ExecutionContext]].
|
||||||
|
* Also an implementation should provide instances of [[TestResponse]] to define the assertion
|
||||||
|
* facilities of the testing library.
|
||||||
|
*
|
||||||
|
* See `JUnitRouteTest` for an example of a concrete implementation.
|
||||||
|
*/
|
||||||
abstract class RouteTest extends AllDirectives {
|
abstract class RouteTest extends AllDirectives {
|
||||||
implicit def system: ActorSystem
|
implicit def system: ActorSystem
|
||||||
implicit def materializer: ActorMaterializer
|
implicit def materializer: Materializer
|
||||||
implicit def executionContext: ExecutionContext = system.dispatcher
|
implicit def executionContext: ExecutionContext = system.dispatcher
|
||||||
|
|
||||||
protected def awaitDuration: FiniteDuration = 500.millis
|
protected def awaitDuration: FiniteDuration = 500.millis
|
||||||
|
|
@ -53,7 +61,7 @@ abstract class RouteTest extends AllDirectives {
|
||||||
/**
|
/**
|
||||||
* Creates a [[TestRoute]] for the main route of an [[HttpApp]].
|
* Creates a [[TestRoute]] for the main route of an [[HttpApp]].
|
||||||
*/
|
*/
|
||||||
def testAppRoute(app: HttpApp): TestRoute = testRoute(app.createRoute)
|
def testAppRoute(app: HttpApp): TestRoute = testRoute(app.createRoute())
|
||||||
|
|
||||||
protected def createTestResponse(response: HttpResponse): TestResponse
|
protected def createTestResponse(response: HttpResponse): TestResponse
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ import scala.reflect.ClassTag
|
||||||
import scala.concurrent.ExecutionContext
|
import scala.concurrent.ExecutionContext
|
||||||
import scala.concurrent.duration.FiniteDuration
|
import scala.concurrent.duration.FiniteDuration
|
||||||
import akka.util.ByteString
|
import akka.util.ByteString
|
||||||
import akka.stream.ActorMaterializer
|
import akka.stream.Materializer
|
||||||
import akka.http.scaladsl.unmarshalling.Unmarshal
|
import akka.http.scaladsl.unmarshalling.Unmarshal
|
||||||
import akka.http.scaladsl.model.HttpResponse
|
import akka.http.scaladsl.model.HttpResponse
|
||||||
import akka.http.impl.util._
|
import akka.http.impl.util._
|
||||||
|
|
@ -18,9 +18,12 @@ import akka.http.javadsl.server.Unmarshaller
|
||||||
import akka.http.javadsl.model._
|
import akka.http.javadsl.model._
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A wrapper for responses
|
* A wrapper for responses.
|
||||||
|
*
|
||||||
|
* To support the testkit API, a third-party testing library needs to implement this class and provide
|
||||||
|
* implementations for the abstract assertion methods.
|
||||||
*/
|
*/
|
||||||
abstract class TestResponse(_response: HttpResponse, awaitAtMost: FiniteDuration)(implicit ec: ExecutionContext, materializer: ActorMaterializer) {
|
abstract class TestResponse(_response: HttpResponse, awaitAtMost: FiniteDuration)(implicit ec: ExecutionContext, materializer: Materializer) {
|
||||||
/**
|
/**
|
||||||
* Returns the strictified entity of the response. It will be strictified on first access.
|
* Returns the strictified entity of the response. It will be strictified on first access.
|
||||||
*/
|
*/
|
||||||
|
|
@ -75,7 +78,7 @@ abstract class TestResponse(_response: HttpResponse, awaitAtMost: FiniteDuration
|
||||||
*/
|
*/
|
||||||
def header[T <: HttpHeader](clazz: Class[T]): T =
|
def header[T <: HttpHeader](clazz: Class[T]): T =
|
||||||
response.header(ClassTag(clazz))
|
response.header(ClassTag(clazz))
|
||||||
.getOrElse(fail(s"Expected header of type ${clazz.getSimpleName} but wasn't found."))
|
.getOrElse(doFail(s"Expected header of type ${clazz.getSimpleName} but wasn't found."))
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Assert on the numeric status code.
|
* Assert on the numeric status code.
|
||||||
|
|
@ -150,7 +153,7 @@ abstract class TestResponse(_response: HttpResponse, awaitAtMost: FiniteDuration
|
||||||
}
|
}
|
||||||
|
|
||||||
private[this] def extractFromResponse[T](f: HttpResponse ⇒ T): T =
|
private[this] def extractFromResponse[T](f: HttpResponse ⇒ T): T =
|
||||||
if (response eq null) fail("Request didn't complete with response")
|
if (response eq null) doFail("Request didn't complete with response")
|
||||||
else f(response)
|
else f(response)
|
||||||
|
|
||||||
protected def assertEqualsKind(expected: AnyRef, actual: AnyRef, kind: String): TestResponse = {
|
protected def assertEqualsKind(expected: AnyRef, actual: AnyRef, kind: String): TestResponse = {
|
||||||
|
|
@ -162,7 +165,13 @@ abstract class TestResponse(_response: HttpResponse, awaitAtMost: FiniteDuration
|
||||||
this
|
this
|
||||||
}
|
}
|
||||||
|
|
||||||
protected def fail(message: String): Nothing
|
// allows to `fail` as an expression
|
||||||
|
private def doFail(message: String): Nothing = {
|
||||||
|
fail(message)
|
||||||
|
throw new IllegalStateException("Shouldn't be reached")
|
||||||
|
}
|
||||||
|
|
||||||
|
protected def fail(message: String): Unit
|
||||||
protected def assertEquals(expected: AnyRef, actual: AnyRef, message: String): Unit
|
protected def assertEquals(expected: AnyRef, actual: AnyRef, message: String): Unit
|
||||||
protected def assertEquals(expected: Int, actual: Int, message: String): Unit
|
protected def assertEquals(expected: Int, actual: Int, message: String): Unit
|
||||||
protected def assertTrue(predicate: Boolean, message: String): Unit
|
protected def assertTrue(predicate: Boolean, message: String): Unit
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,14 @@ package akka.http.javadsl.testkit
|
||||||
import akka.http.javadsl.model.HttpRequest
|
import akka.http.javadsl.model.HttpRequest
|
||||||
import akka.http.javadsl.server.Route
|
import akka.http.javadsl.server.Route
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A wrapped route that has a `run` method to run a request through the underlying route to create
|
||||||
|
* a [[TestResponse]].
|
||||||
|
*
|
||||||
|
* A TestRoute is created by deriving a test class from the concrete RouteTest implementation for your
|
||||||
|
* testing framework (like [[JUnitRouteTest]] for JUnit) and then using its `testRoute` method to wrap
|
||||||
|
* a route with testing support.
|
||||||
|
*/
|
||||||
trait TestRoute {
|
trait TestRoute {
|
||||||
def underlying: Route
|
def underlying: Route
|
||||||
def run(request: HttpRequest): TestResponse
|
def run(request: HttpRequest): TestResponse
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue