使用 PestPHP 测试 JSON:API 端点
发布于 作者: Steve McDougall
JSON:API 为使用查询参数过滤、排序和将额外数据包含到请求数据中提供了许多选项。测试这可能会让人沮丧 - 但在本教程中,我将逐步介绍我如何处理测试这些端点。
让我们以一个想要获取项目列表的端点为例,该端点具有以下数据模型
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 响应中返回一个 JSON:API 资源。让我们快速看一下查询,它将基于我之前关于 有效 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 端点?这是使用 PestPHP 在 Laravel 中测试 JSON:API 端点的简单指南。这些原则可以应用于您在 API 中可能需要执行的任何其他测试。
技术作家,任职于 Laravel 新闻,开发者倡导者,任职于 Treblle。API 专家,经验丰富的 PHP/Laravel 工程师。 YouTube 直播主.