Provides the main api for creating and sending REST Web service requests (as a trait for mixing in).
Provides a DSL for simplifying REST system tests.
Adds ScalaTest support to the RestTest Dsl.
Adds ScalaTest support to the RestTest Dsl.
The should
keyword is added to Api.RequestBuilder and Api.Response expressions, the
RequestBuilder
is executed first and should
applied to the Response
.
The have
keyword supports Extractors.ExtractorLikes. See ExtractorToHavePropertyMatcher for more details.
using (_ url "http://api.rest.org/person") { implicit rb => GET should have (statusCode(Status.OK), jsonBodyAsList[Person] === EmptyList) val (status, id) = POST body personJson returning (statusCode, headerText("X-Person-Id")) status should be(Status.Created) val foo = GET / id should have (statusCode(Status.OK), jsonBodyAs[Person] === Jason) GET should have (statusCode === Status.OK, jsonBodyAsList[Person] === Seq(Jason)) DELETE / id should have (statusCode === Status.OK) GET / id should have (statusCode === Status.NotFound) GET should have (statusCode(Status.OK), jsonBodyAsList[Person] === EmptyList) }
The test driver defines the Api.HttpClient and initial Api.RequestBuilder used to execute Rest Tests.
The test driver defines the Api.HttpClient and initial Api.RequestBuilder used to execute Rest Tests.
Users mix-in their preferred TestDriver implementation, to execute their tests.
class PersonSpec extends FlatSpec { this: TestDriver => val EmptyList = Seq[Person]() "/person (collection)" should "be empty" in { GET / "person" asserting (StatusCode === Status.OK, BodyAsPersonList === EmptyList) } } class PersonUnitSpec extends PersonSpec with SprayUnitTestDriver with MyService class PersonSystemSpec extends PersonSpec with JerseySystemTestDriver { override val baseUrl = "http://localhost:9000" }
Subclasses implement the interface supplying a httpClient to execute the Requests and a defBuilder which provides the base configuration for all tests. All tests should support relative paths, this enables the same test code to be executed as a unit test and a system test. To support this the defBuilder for system test drivers should supply the baseUrl some how.
Provides the main api for creating and sending REST Web service requests (as an object for importing).
Provides the main api for creating and sending REST Web service requests (as an object for importing).
val request = Request(GET, new URI("http://api.rest.org/person", Map(), None)) val response = driver.execute(request) response.statusCode should be(Status.OK) response.body match { Some(body) => objectMapper.readValue[List[Person]](body) should have length(0) None => fail("Expected a body")) }
or using the Api.RequestBuilder
val request = driver.execute(RequestBuilder().withUrl("http://api.rest.org/person/").withMethod(GET))
This provides the basic interface used to implement the Dsl, users are expected to use the Dsl.
Provides a DSL for simplifying REST system tests. This is meant to be used with ScalaTest or similar testing framework.
For example to post a json document to a REST endpoint and check the statusCode:
Or to get a json document from a REST endpoint and convert the json array to a List of Person objects:
Finally a more complete example that using a ScalaTest Spec to verify a simple REST API.
Configuring a Request
The DSL centers around the Api.RequestBuilder, which specifies the properties of the request. Most expressions begin with the HTTP Api.Method followed by a call to RichRequestBuilder, this converts the
Method
to a Api.RequestBuilder. The resultingRequestBuilder
contains both theMethod
and secondary property. For example:GET url "http://api.rest.org/person"
is the same as
RequestBuilder().withMethod(GET).withUrl("http://api.rest.org/person")
The
RequestBuilder
DSL also supports default values passed implicitly into expressions, for example:creates a
RequestBuilder
with a method, url and accept header set. The default values are normal expressed the with the using expression.Executing a Request
There are three ways to execute a request: RichRequestBuilder
.execute
, RichResponse.returning
, RichRequestBuilder.asserting
, these can all be applied toRequestBuilder
instances.The
execute
method executes the request with the implicit Api.HttpClient and returns theResponse
.The
returning
method executes the request like theexecute
method, except it applies one or more Extractors to theResponse
to return only the extracted information.The
asserting
method executes the request like theexecute
method, except it verifies the specified value of one or moreResponse
values.asserting
is normally used with extractors, see [RichExtractor] for more information.asserting
andreturning
methods can be used in the same expression.Working with Extractors
Extractors are simply functions that take a Api.Response are extract or convert part of its contents. Extracts are written to assume that the data they require is in the response, if it is not they throw an Exception (failing the test). See Extractors for more information on the available default
Extractor
s And how to implement your own.