Php – Laravel Trying To Unit Test API JSON Response

laravelphpphpunitunit-testing

Trying to learn too many new things at once here (Laravel, PHPUnit, etc), so this is probably just a tired brain problem, would still appreciate some help.

I have a very basic 'Blog' project using Laravel as the API layer and AngularJS as the front end. I want to unit test the API end-points but I am having trouble figuring out how to process JSON while in my test functions.

When I try to run testGetBlogPosts() I see what looks like the JSON output in my CLI, but I am unable to json_decode() and check that certain parts of the object match my expected result. Here I simply want to make sure that the ID on the first object in the result array is ID "1".

The result I receive from the test is:
1) ExampleTest::testGetBlogPosts
ErrorException: Trying to get property of non-object

Any help or suggestions is much appreciated!

TL;DR: Test case is not correctly processing JSON response from API endpoint

Controller

class HomeController extends BaseController {

    /*
    |--------------------------------------------------------------------------
    | Default Home Controller
    |--------------------------------------------------------------------------
    |
    | You may wish to use controllers instead of, or in addition to, Closure
    | based routes. That's great! Here is an example controller method to
    | get you started. To route to this controller, just add the route:
    |
    |   Route::get('/', 'HomeController@showWelcome');
    |
    */
    public function showWelcome()
    {
        return View::make('hello');
    }

    public function getBlogPosts()
    {
        $posts = Post::get()->take(5)->toJson();
        // echo $posts; PER THE ACCEPTED ANSWER, RETURN NOT ECHO
        return $posts;
    }
    public function getSinglePost($postId)
    {
        $posts = Post::find($postId)->toJson();
        // echo $posts; PER THE ACCEPTED ANSWER, RETURN NOT ECHO
        return $posts;
    }

}

Test File

class ExampleTest extends TestCase {

    /**
     * A basic functional test example.
     *
     * @return void
     */
    public function testBasicExample()
    {
        $crawler = $this->client->request('GET', '/');
        $this->assertTrue($this->client->getResponse()->isOk());
    }

    public function testGetBlogPosts()
    {
        $response = $this->call('GET', 'api/getBlogPosts');

        $array = json_decode($response);
        $result = false;
        if($array[0]->id == 1)
        {
            $result = true;
        }
        $this->assertEquals(true, $result);
    }
}

As requested, the full test output

root@homestead:/home/vagrant/Laravel/Homestead/Blog# phpunit PHPUnit
3.7.28 by Sebastian Bergmann.

Configuration read from
/home/vagrant/Laravel/Homestead/Blog/phpunit.xml

.E[{"id":"1","user_id":"1","title":"This is a test
post","post_body":"testststs","created_at":"2014-08-07
19:26:26","updated_at":"2014-08-07
19:26:26"},{"id":"2","user_id":"75","title":"Libero rerum rem
praesentium et et at doloribus asperiores.","post_body":"Commodi aut
beatae aut veritatis eum soluta sint. In aut cumque iure
quis.","created_at":"2014-08-07 19:26:26","updated_at":"2014-08-07
19:26:26"}]

Time: 1.85 seconds, Memory: 18.50Mb

There was 1 error:

1) ExampleTest::testGetBlogPosts ErrorException: Trying to get
property of non-object

/home/vagrant/Laravel/Homestead/Blog/app/tests/ExampleTest.php:22

FAILURES! Tests: 2, Assertions: 1, Errors: 1.

If I go to this endpoint in a browser I get this

[
{
id: 1,
user_id: 1,
title: "This is a test post",
subtitle: "",
post_body: "testststs",
created_at: "2014-08-07 19:26:04",
updated_at: "2014-08-07 19:26:04"
},
{
id: 2,
user_id: 18,
title: "Rem deserunt dolor odit tempore qui eaque labore.",
subtitle: "",
post_body: "Ea a adipisci molestiae vel dignissimos. Ea blanditiis et est.",
created_at: "2014-08-07 19:26:04",
updated_at: "2014-08-07 19:26:04"
}
]

Best Solution

Hope you figured it out by now but here is what I use:

$array = json_decode($response->getContent());