Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Laravel Trying To Unit Test API JSON Response

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"
}
]
like image 599
Shane Avatar asked Aug 07 '14 19:08

Shane


2 Answers

You can call the json method directly off the response object.

$response = $this->getJson('/foo');
$json = $response->json(); // ['foo' => 'bar', 'baz' => 'boo']

It also accepts a key as an argument.

$foo = $response->json('foo'); // 'bar'
like image 191
Jeff Puckett Avatar answered Oct 12 '22 21:10

Jeff Puckett


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

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

like image 23
vladsch Avatar answered Oct 12 '22 20:10

vladsch