У меня есть это вложенное отношение, я немного не уверен, как я assertJson ответ в тесте phpunit.

< Сильный > FilmController

public function show(string $id)
{
    $film = Film::with([
        'account.user:id,account_id,location_id,name',
        'account.user.location:id,city'
    ])->findOrFail($id);
}

< Сильный > FilmControllerTest

public function getFilmTest()
{
    $film = factory(Film::class)->create();

    $response = $this->json('GET', '/film/' . $film->id)
        ->assertStatus(200);

    $response
        ->assertExactJson([
            'id' => $film->id,
            'description' => $film->description,
            'account' => $film->account->toArray(),
            'account.user' => $film->account->user->toArray(),
            'account.user.location' => $film->account->user->location->toArray()
        ]);
}

Очевидно, что это не работает, потому что он возвращает каждый столбец для пользователя, я немного незнаком с тем, как вы тестируете вложенные отношения с кодом, который вам нужен, так что я не уверен с toArray, может кто-нибудь помочь?

1
user12247297 23 Ноя 2019 в 20:00

1 ответ

Лучший ответ

Тестирование - это место, где вы выбрасываете СУХОЙ (не повторяйтесь) и заменяете его жестко закодированными решениями. Почему? просто вы хотите, чтобы тест всегда давал одни и те же результаты и не был привязан к логике модели, умным методам и т. д. Прочтите эту замечательную статью.

Просто жестко запишите структуру, которую вы ожидаете увидеть. Если вы измените что-либо в своей модели на подход с использованием массива, тест все равно пройдет, даже если ваше имя отсутствует в ответе. Потому что вы используете тот же подход к трансформации, что и тестирование. К настоящему времени я протестировал множество приложений Laravel, и этот подход я предпочитаю.

$account = $film->account;
$user = $account->user;
$location = $user->location;

$response->assertExactJson([
    'description' => $film->description,
    'account' => [
        'name' => $account->name,
        'user' => [
          'name' => $user->name,
          'location' => [
            'city' => $location->city,
           ],
        ],
    ],
]);

Не проверяйте id, так как база данных будет обрабатывать его и является излишним для тестирования. Если вы хотите проверить эти вещи, я бы предпочел использовать assertJsonStructure(), который не подтверждает данные, но проверяет, правильно ли установлены ключи JSON. Я думаю, что было бы справедливо включить оба, просто всегда сначала проверяйте структуру JSON, так как это, вероятно, будет проще всего пройти.

$response->assertJsonStructure([
    'id',
    'description',
    'account' => [
        'id',
        'name',
        'user' => [
          'id',
          'name',
          'location' => [
            'id',
            'city',
           ],
        ],
    ],
]);
0
mrhn 24 Ноя 2019 в 11:34