Reputation: 816
I am creating a Laravel application and using PHP Unit for my tests. I am trying to write tests for my endpoints. I have an endpoint which returns a JSON response of all clients in the database like so:
{
data: [
{
id: 1,
name: "test",
password: "p@ssword",
description: "test client",
ip: "192.168.0.1",
created: "2017-05-18T19:16:20+00:00",
updated: "2017-05-18T19:16:23+00:00"
},
{
id: 2,
name: "test",
password: "p@ssword",
description: "test client 2",
ip: "192.168.0.2",
created: "2017-05-22T19:16:20+00:00",
updated: "2017-05-22T19:16:23+00:00"
}
]
}
I have then created a ClientControllerTest which will check that JSON response using a testing database and Faker. My ClientControllerTest is as follows:
<?php
namespace Tests\App\Http\Controllers;
use Tests\TestCase;
use Carbon\Carbon;
use App\Client;
use Illuminate\Foundation\Testing\DatabaseMigrations;
class ClientsControllerTest extends TestCase
{
use DatabaseMigrations;
public function setUp()
{
parent::setUp();
Carbon::setTestNow(Carbon::now('UTC'));
}
public function tearDown()
{
parent::tearDown();
Carbon::setTestNow();
}
/** @test */
public function index_status_code_should_be_200()
{
$this->get('api/clients')->assertStatus(200);
}
/** @test */
public function index_should_return_a_collection_of_records()
{
$clients = factory(Client::class, 2)->create();
$response = $this->json('GET', 'api/clients');
$response->assertStatus(200);
$content = json_decode($response->getContent(), true);
$this->assertArrayHasKey('data', $content);
foreach ($clients as $client) {
$response->assertJson([
"id" => $client->id,
"name" => $client->name,
"password" => $client->password,
"description" => $client->description,
"ip" => $client->ip,
"created" => $client->created_at->toIso8601String(),
"updated" => $client->updated_at->toIso8601String()
]);
}
}
}
However when I try to run PHPUnit, I am getting a strange error which seems to assert that $response->assertJSON is failing even though I can see the output in the error message? Error message is as follows:
1) Tests\App\Http\Controllers\ClientsControllerTest::index_should_return_a_collection_of_records
Unable to find JSON:
[{
"id": 1,
"name": "Christophe Sporer",
"password": "VaK~\\g",
"description": "Saepe nisi accusamus numquam dolores voluptate id.",
"ip": "195.177.237.184",
"created": "2017-05-23T19:53:43+00:00",
"updated": "2017-05-23T19:53:43+00:00"
}]
within response JSON:
[{
"data": [
{
"id": 1,
"name": "Christophe Sporer",
"password": "VaK~\\g",
"description": "Saepe nisi accusamus numquam dolores voluptate id.",
"ip": "195.177.237.184",
"created": "2017-05-23T19:53:43+00:00",
"updated": "2017-05-23T19:53:43+00:00"
},
{
"id": 2,
"name": "Miss Virginie Johnson",
"password": "e1\"~q\\*oSe^",
"description": "Nihil earum quia praesentium iste nihil nulla qui occaecati non et perspiciatis.",
"ip": "110.125.57.83",
"created": "2017-05-23T19:53:43+00:00",
"updated": "2017-05-23T19:53:43+00:00"
}
]
}].
Failed asserting that an array has the subset Array &0 (
'id' => 1
'name' => 'Christophe Sporer'
'password' => 'VaK~\g'
'description' => 'Saepe nisi accusamus numquam dolores voluptate id.'
'ip' => '195.177.237.184'
'created' => '2017-05-23T19:53:43+00:00'
'updated' => '2017-05-23T19:53:43+00:00'
).
I am a bit confused as to why this is failing as PHPUnit doesn't seem to provide any more information and I did assert that the request to api/clients worked and returned a 200 so I know the response is accurate.
Any help is appreciated, thanks!
Upvotes: 3
Views: 8619
Reputation: 39444
Your response data has the format { 'data' => [ ... ] }
, where the subset you want is inside the [ ... ]
. However, you are asking to find the structure { 'id': ..., ... }
, which does not exist at the top level. You need to assert the JSON within the data member of $response
.
You can instead use:
assertJson([ 'data' => [ "id" => $client->id, ... ] ])
Upvotes: 7