Laravel Пытается Выполнить Модульное Тестирование Ответа API JSON


Пытаясь узнать здесь слишком много нового сразу (Laravel, PHPUnit и т. Д.), Так что это, вероятно, просто проблема с усталым мозгом, все равно буду признателен за помощь.

У меня есть очень простой проект "Блог", использующий Laravel в качестве уровня API и AngularJS в качестве интерфейса. Я хочу провести модульное тестирование конечных точек API, но мне трудно понять, как обрабатывать JSON в моих тестовых функциях.

Когда я пытаюсь запустить testGetBlogPosts(), я вижу, как выглядит вывод JSON в моем CLI, но я не могу json_decode() и проверить, соответствуют ли определенные части объекта моему ожидаемому результату. Здесь я просто хочу убедиться, что идентификатор первого объекта в результирующем массиве равен ID "1".

Результат, который я получаю от теста, является: 1) Примерный тест::Тестовые сообщения в блогах Исключение ErrorException: Попытка получить свойство не-объекта

Мы будем очень признательны за любую помощь или предложения!

TL;DR: Тестовый случай неправильно обрабатывает ответ JSON от API конечная точка

Контроллер

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;
    }

}

Тестовый файл

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);
    }
}

Как и было запрошено, полный тестовый вывод

Root@homestead:/home/vagrant/Laravel/Homestead/Blog #пхпунит ПХПУнит 3.7.28 Себастьяна Бергмана.

Конфигурация, считанная из /home/vagrant/Laravel/Homestead/Blog/phpunit.xml

.E[{"идентификатор": "1", "идентификатор пользователя": "1", "название": "Это тест сообщение", "post_body": "testststs", "created_at": "2014-08-07 19:26:26", "обновлен_ат": "2014-08-07 19:26:26"},{" идентификатор": "2", "идентификатор пользователя": "75", "название": "Libero rerum rem praesentium et et в doloribus asperiores"., "post_body": "Commodi aut beatae aut veritatis eum soluta sint.", "сообщение": "Commodi aut beatae aut veritatis eum soluta sint. В aut cumque iure quis.", "создан_ат":"2014-08-07 19:26:26"," обновлен_ат":"2014-08-07 19:26:26"}]

Время: 1,85 секунды, Память: 18,50 Мб

Произошла 1 ошибка:

1) Exampletest::testgetblogposts Исключение ошибки: Попытка получить свойство не-объекта

/главная/бродяга/Ларавель/Усадьба/Блог/приложение/тесты/exampletest.php:22

НЕУДАЧИ! Тесты: 2, Утверждения: 1, Ошибки: 1.

Если я перейду к этой конечной точке в браузере, я получу это

[
{
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"
}
]
Author: Shane, 2014-08-07

4 answers

Метод getBlogPosts() в вашем контроллере повторяет $post, а не возвращает его. Это означает, что в $response в вашем тесте не будет ничего, что могло бы json_decode.

 4
Author: Don't Panic, 2016-07-06 18:34:23

Надеюсь, вы уже поняли это, но вот что я использую:

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

 9
Author: vladsch, 2015-02-11 21:12:32

Добавление метода в /tests/TestCase.php очень помогает:

/**
 * dumps json result
 * @param string $function can be print_r, var_dump or var_export
 * @param boolean $json_decode 
 */
public function dump($function = 'var_export', $json_decode = true) {
    $content = $this->response->getContent();
    if ($json_decode) {
        $content = json_decode($content, true);
    }
    // ❤ ✓ ☀ ★ ☆ ☂ ♞ ☯ ☭ € ☎ ∞ ❄ ♫  ☼
    $seperator = '❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤';
    echo PHP_EOL . $seperator . PHP_EOL;
    $function($content);
    echo $seperator . PHP_EOL;
    return $this;
}

Затем вы можете вызвать его в любой момент после вызова json:

public function testInvalidPostID() {
    $this->json('PUT', '/posts/2222/sh-comments/1001', [
        'input' => 'SomeThing'
            ], [
        'Authorization' => 'Bearer ' . app('jwt')->getTokenForUser(2)
    ])->dump() //dumpnig output as array
      ->seeJsonStructure(['errors' => [
            '*' => [
                'message'
            ]
        ]
    ])->assertResponseStatus(404);
}
 2
Author: HPM, 2016-12-21 23:00:14

Вы можете вызвать метод json непосредственно из объекта ответа.

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

Он также принимает ключ в качестве аргумента.

$foo = $response->json('foo'); // 'bar'
 0
Author: Jeff Puckett, 2018-08-18 04:01:17