61

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()?

rap-2-h
  • 30,204
  • 37
  • 167
  • 263

10 Answers10

99

Proper way to get the content is:

$content = $this->get('/v1/users/1')->decodeResponseJson();
Jan Tlapák
  • 975
  • 8
  • 10
51

Currently, in 5.3 this is working...

$content = $this->get('/v1/users/1')->response->getContent();

However, it does break the chain 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();
medilies
  • 1,811
  • 1
  • 8
  • 32
Mike McLin
  • 3,627
  • 7
  • 41
  • 49
17

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.

Kalema Edgar
  • 369
  • 5
  • 17
13

I like to use the json method when working with json, instead of ->get()

$data = $this->json('GET', $url)->seeStatusCode(200)->decodeResponseJson();
cmac
  • 3,123
  • 6
  • 36
  • 49
9

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();
rap-2-h
  • 30,204
  • 37
  • 167
  • 263
Daniel
  • 1,403
  • 1
  • 14
  • 30
  • 1
    The test case doesn't have a `getContent()` method. The `get()` method is a fluent helper that returns the test case (so you can chain multiple assertions). The test case does have a `response` property that will return your response object (instead of the test case). Then you can call `getContent()` on that response object. See my answer for more details. – Mike McLin Sep 14 '16 at 03:43
7

Simple way:

$this->getJson('api/threads')->content()
Mwthreex
  • 913
  • 1
  • 11
  • 24
6

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.

Macdonald
  • 880
  • 7
  • 21
Toby
  • 61
  • 1
  • 3
5

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);
Shadman
  • 755
  • 2
  • 11
  • 19
0

You can just call:

$data = $response->json();

Eleandro Duzentos
  • 1,370
  • 18
  • 36
-1
$response = $this->json('POST', '/products', $data);
$data = $response->getData();
Dharman
  • 30,962
  • 25
  • 85
  • 135
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the [help center](https://stackoverflow.com/help/how-to-answer). – Ethan Sep 04 '22 at 19:19