Тестирование конечных точек JSON:API с PestPHP
Давайте рассмотрим пример конечной точки, где мы хотим получить список проектов со следующей моделью данных:
Project:
attributes:
id: string
name: string
description: text
status: string (Enum: planning, in-progress, in-testing, done)
active: boolean
relationships:
owner: BelongsTo (User)
client: BelongsTo (Client)
Я не буду показывать код контроллера, так как это несколько субъективно. Однако мы должны вернуть ресурс JSON:API внутри ответа JSON. Давайте быстро взглянем на запрос, который будет основан на моём предыдущем руководстве Laravel: Эффективный Eloquent.
final class FetchProjectsByUser
{
public function handle(Builder $builder, string $user): Builder
{
return QueryBuilder::for(
subject: $builder,
)->allowedIncludes(
includes: ['owner', 'client'],
)->allowedFilters(
filters: ['status', 'active'],
)->where(
'user_id',
$user,
)->getEloquentBuilder();
}
}
С этого момента мы можем начать тестирование конечной точки, чтобы убедиться, что все параметры доступны. Мы хотим получить все проекты, все активные или неактивные, с различными статусами, и мы хотим гарантировать, что можем включить информацию как о владельце, так и о клиенте, если она будет запрошена. Но как насчёт несчастных тестов пути?
Мой первый тест при работе с такими конечными точками заключается в обеспечении того, чтобы пользователи, не прошедшие проверку аутентификацию, не могли получить к ним доступ. Эти тесты предполагают, что контроллер, который мы хотим использовать называется IndexController
.
it('returns the correct status code if unauthenticated', function (): void {
getJson(
uri: action(IndexController::class),
)->assertStatus(
status: Http::UNAUTHORIZED->value,
);
});
Этот тест обязательный, чтобы убедиться, что вы можете или не можете получить доступ к конечной точке в зависимости от того, вошли вы в систему или нет. Затем мы можем проверить, чтобы убедиться, что мы получаем правильный код состояния, если вошли в систему.
it('returns the correct status code for users', function (): void {
actingAs(User::factory()->create())->getJson(
uri: action(IndexController::class),
)->assertStatus(
status: Http::OK->value,
);
});
Такие простые тесты часто упускают из виду, и их следует добавить, чтобы убедиться, что вы правильно понимаете простые вещи. В прошлом и пропускал их, полагая, что всё будет работать, но обнаружил, что вызывал проблему с добавленным мной кодом, который вызывал ошибки с кодом 500 на определённых конечных точках. Далее, мы можем приступить к тестированию дополнительных функций JSON:API.
it('can fetch the projects client', function (): void {
actingAs(User::factory()->create())->getJson(
uri: action(IndexController::class, [
'include' => 'client',
]),
)->assertStatus(
status: Http::OK->value,
)->assertJson(fn (AssertableJson $json) => $json
->first(fn (AssertableJson $json) => $json
->has('relationships.client')
->etc()
)
);
});
Мы хотим проверить, существует ли здесь взаимосвязь, так как мы не получим полной информации, включая эту взаимосвязь, достаточно только знать, что запрашивать для уточнения. Однако это часть дизайна JSON:API.
Следующим шагом является фильтрация API, чтобы мы могли получать конкретные проекты на основе фильтруемых атрибутов, которые мы добавили в наш запрос.
it('can filter to active projects only', function (): void {
actingAs(User::factory()->create())->getJson(
uri: action(IndexController::class, [
'filter[active]' => true,
]),
)->assertStatus(
status: Http::OK->value,
)->assertJson(fn (AssertableJson $json) => $json
->each(fn (AssertableJson $json) => $json
->where('attributes.active', true)
->etc()
)
);
});
Мы можем применить этот подход к любым фильтрам используемым для конечных точек, позволяя любому, кто работает с нашим API, получать именно те данные, которые ему нужны.
Как вы проводите тестирование конечных точек API? Это простое руководство по тестированию конечных точек JSON:API в Laravel с использованием PestPHP. Принципы могут быть применены к любым другим тестам, которые вам могут понадобиться в вашем API.