Laravel testing, get JSON content
LaravelLaravel 5PhpunitLaravel Problem Overview
In Laravel's unit test, I can test a JSON API like that:
$this->post('/user', ['name' => 'Sally'])
->seeJson([
'created' => true,
]);
But what if I want to use the response. How can I get the JSON response (as an array) using $this->post()
?
Laravel Solutions
Solution 1 - Laravel
Proper way to get the content is:
$content = $this->get('/v1/users/1')->decodeResponseJson();
Solution 2 - Laravel
Currently in 5.3 this is working...
$content = $this->get('/v1/users/1')->response->getContent()
;
It does break the chain, however since response
returns the response and not the test runner. So, you should make your chainable assertions before fetching the response, like so...
$content = $this->get('/v1/users/1')->seeStatusCode(200)->response->getContent()
;
Solution 3 - Laravel
I like to use the json method when working with json, instead of ->get()
$data = $this->json('GET', $url)->seeStatusCode(200)->decodeResponseJson();
Solution 4 - Laravel
As at Laravel 8, this worked for me.
I was returning an automatically generated field (balance) after the POST request has created the entity.
The response was in the structure {"attributes":{"balance":12345}}
$response = $this->postJson('api/v1/authors', [
'firstName' => 'John',
'lastName' => 'Doe',
])->assertStatus(201);
$balance = $response->decodeResponseJson()['attributes']['balance'];
decodeResponseJson
will pick the response and transform it to an array for manipulation.
Using getContent()
returns json and you will have to use json_decode
on the returned data to turn it into an array.
Solution 5 - Laravel
I hit a similar problem and could not get $this->getResponse()->getContent() working with the built in $this->get() method. I tried several variations with no success.
Instead I had to change the call to return the full http response and get the content out of that.
// Original (not working)
$content = $this->get('/v1/users/1')->getContent();
// New (working)
$content = $this->call('GET', '/v1/users/1')->getContent();
Solution 6 - Laravel
Found a better way:
$response = $this->json('POST', '/order', $data);
$responseData = $response->getOriginalContent(); // saves the response as an array
$responseData['value'] // you can now access the array values
This method returns the response json as an array.
Solution 7 - Laravel
Simple way:
$this->getJson('api/threads')->content()
Solution 8 - Laravel
Just want to share, I have used the same in $this->json()
like:
$response = $this->json('POST', '/order', $data)->response->getContent();
But I added one more line to use json response and decode otherwise decodeResponseJson()
was not working for me.
$json = json_decode($response);
Solution 9 - Laravel
$response = $this->json('POST', '/products', $data);
$data = $response->getData();