Test Requests
Introduction
This chapter documents the test helpers that are available via the jsonApi() method that the MakesJsonApiRequests trait adds to your test class. These test helpers are designed to help you fluently create test JSON:API requests.
Expected Resource Type
When calling the jsonApi method, it is important to provide the resource type that you expect in the response. This allows you to then pass models to our test assertions, as the assertions will use the expected resource type when checking if the models are in the response JSON.
The expected resource type can be set using the expects method. For example:
$response = $this->jsonApi()->expects('posts')->get('/api/v1/posts');If you prefer, you can also provide the expected resource type to the jsonApi method:
$response = $this->jsonApi('posts')->get('/api/v1/posts');Query Parameters
The following methods allow you to set query parameters when creating test JSON:API requests:
Query
The query method allows you to set multiple query parameters in a single method:
$response = $this->jsonApi()->expects('posts')->query([
'include' => 'author,tags',
'page' => ['number' => 1, 'size' => 10],
])->get('/api/v1/posts');This is equivalent to the following request:
GET /api/v1/posts?include=author,tags&page[number]=1&page[size]=10 HTTP/1.1
Accept: application/vnd.api+jsonInclude Paths
The includePaths method allows you to fluently set the include query parameter:
$response = $this
->jsonApi()
->expects('posts')
->includePaths('author', 'tags')
->get('/api/v1/posts');This is equivalent to the following request:
GET /api/v1/posts?include=author,tags HTTP/1.1
Accept: application/vnd.api+jsonSparse Fields
The sparseFields method allows you to fluently set the fields query parameter for a specific resource type. For example:
$response = $this
->jsonApi()
->expects('posts')
->sparseFields('posts', ['title', 'slug', 'author'])
->sparseFields('users', ['name'])
->get('/api/v1/posts');This is equivalent to the following request:
GET /api/v1/posts?fields[posts]=title,slug,author&fields[users]=name HTTP/1.1
Accept: application/vnd.api+jsonFilter
The filter method allows you to fluently set the filter query parameter:
$response = $this
->jsonApi()
->expects('posts')
->filter(['published' => 'true'])
->get('/api/v1/posts');This is equivalent to the following request:
GET /api/v1/posts?filter[published]=true HTTP/1.1
Accept: application/vnd.api+jsonIf you provide models as filter values, these will be converted to their route keys. For example:
$posts = Post::factory()->count(3)->create();
$response = $this
->jsonApi()
->expects('posts')
->filter(['id' => $posts])
->get('/api/v1/posts');Sort
The sort method allows you to fluently set the sort query parameter:
$response = $this
->jsonApi()
->expects('posts')
->sort('-publishedAt', 'title')
->get('/api/v1/posts');This is equivalent to the following request:
GET /api/v1/posts?sort=-publishedAt,title HTTP/1.1
Accept: application/vnd.api+jsonTIP
You should pair the sort method with our ordered assertions - for example, assertFetchedManyInOrder.
Page
The page method allows you to fluently set the page query parameter:
$response = $this
->jsonApi()
->expects('posts')
->page(['number' => 1, size => 10])
->get('/api/v1/posts');This is equivalent to the following request:
GET /api/v1/posts?page[number]=1&page[size]=10 HTTP/1.1
Accept: application/vnd.api+jsonIf you provide models as page values, these will be converted to their route keys. For example:
$posts = Post::factory()->count(3)->create();
$response = $this
->jsonApi()
->expects('posts')
->page(['after' => $posts[0]])
->get('/api/v1/posts');Request Body and Headers
The following methods allow you to set request body content when creating test JSON:API requests:
withData
The withData method allows you to set the request content to a JSON document, that contains the provided value as the data member.
For example:
$response = $this->jsonApi()->withData([
'type' => 'posts',
'attributes' => [
'content' => '...',
'title' => 'Hello World!',
'slug' => 'hello-world',
],
])->post('/api/v1/posts');Is equivalent to the following request:
POST /api/v1/posts HTTP/1.1
Accept: application/vnd.api+json
Content-Type: application/vnd.api+json
{
"data": {
"type": "posts",
"attributes": {
"content": "...",
"title": "Hello World!",
"slug": "hello-world"
}
}
}withJson
The withJson method allows you to set the entire JSON body content. For example:
$response = $this->jsonApi()->withJson([
'meta' => [
'foo' => 'bar',
],
])->post('/api/v1/posts');Is equivalent to the following request:
POST /api/v1/posts HTTP/1.1
Accept: application/vnd.api+json
Content-Type: application/vnd.api+json
{
"meta": {
"foo": "bar"
}
}withPayload
The withPayload method should be used when you are sending request content that is not JSON:API content. This should be used in combination with any of the helper methods that allow you to set an alternative content type.
For example:
$response = $this->jsonApi()->asFormUrlEncoded()->withPayload([
'foo' => 'bar',
'baz' => 'bat',
])->post('/api/v1/posts');Is equivalent to the following request:
POST /api/v1/posts HTTP/1.1
Accept: application/vnd.api+json
Content-Type: application/x-www-form-urlencoded
foo=bar&baz=batcontentType
The contentType method allows you to set an alternative Content-Type header. This is useful when testing requests that send non-JSON:API content, but expect a JSON:API response.
Typically you would pair this with the withPayload method to set the non-JSON:API request body.
For example:
$response = $this
->jsonApi()
->contentType('application/x-www-form-urlencoded')
->withPayload(['foo' => 'bar', 'baz' => 'bat'])
->post('/api/v1/posts');Is equivalent to the following request:
POST /api/v1/posts HTTP/1.1
Accept: application/vnd.api+json
Content-Type: application/x-www-form-urlencoded
foo=bar&baz=batasFormUrlEncoded
The asFormUrlEncoded method is a short-hand for setting the Content-Type header to application/x-www-form-urlencoded.
asMultiPartFormData
The asMultiPartFormData method is a short-hand for setting the Content-Type header to multipart/form-data.
withHeaders and withHeader
The withHeaders method allows you to fluently set multiple headers when constructing your test request. The withHeader method sets a single header.
For example:
$response = $this->jsonApi()->expects('posts')->withHeaders([
'X-Foo' => 'Bar',
'X-Baz' => 'Bat',
])->get('/api/v1/posts');
// is equivalent to:
$response = $this
->jsonApi()
->expects('posts')
->withHeader('X-Foo', 'Bar')
->withHeader('X-Baz', 'Bat')
->get('/api/v1/posts');HTTP Verbs
Methods exist for the following HTTP verbs:
getpostpatchputdelete
All these methods expect the first argument to be a string URI, and the second argument is an optional array of headers.
This makes these methods different from the Laravel equivalents, which accept an array of data for verbs such as post. You should instead use our fluent Request Body helpers to set the request content before calling the HTTP verb method.