Vortex
Vortex

Reputation: 816

JSON Response Assert Fails PHP Unit

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

Answers (1)

bishop
bishop

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

Related Questions