3

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!

0

1 Answer 1

7

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, ... ] ])
Sign up to request clarification or add additional context in comments.

2 Comments

Just as a sidenote, you can also use assertJsonFragment as of Laravel 5.4
assertJsonFragment is much more helpful

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.