You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为Laravel中的GraphQL应用编写单元测试?

嘿,我来帮你梳理下Laravel中GraphQL应用的单元测试方案——当然不止用PHPUnit发简单请求啦,有好几种更优雅的方式可以选择,结合你给出的ClientQuery代码,我给你拆解几个实用方案:

Laravel GraphQL应用单元测试的进阶方案

1. 直接测试Resolver逻辑(单元测试核心)

其实你完全可以跳过HTTP请求层,直接实例化你的Query类,调用resolve方法来测试业务逻辑,这样测试更聚焦核心逻辑,运行速度也更快。

针对你的ClientQuery,可以这么写测试:

use Tests\TestCase;
use App\GraphQL\Queries\ClientQuery;
use App\Models\Client;
use GraphQL\Type\Definition\ResolveInfo;

class ClientQueryTest extends TestCase
{
    public function test_resolve_returns_correct_client()
    {
        // 先创建测试数据
        $client = Client::factory()->create();
        
        // 实例化Query类
        $query = new ClientQuery();
        
        // 模拟resolve需要的参数(root和context可以传空数组,ResolveInfo直接mock)
        $resolveInfo = $this->createMock(ResolveInfo::class);
        
        // 调用resolve方法
        $result = $query->resolve([], ['id' => $client->id], [], $resolveInfo);
        
        // 断言结果符合预期
        $this->assertEquals($client->id, $result->id);
        $this->assertInstanceOf(Client::class, $result);
    }
    
    public function test_resolve_returns_null_for_nonexistent_id()
    {
        $query = new ClientQuery();
        $resolveInfo = $this->createMock(ResolveInfo::class);
        
        $result = $query->resolve([], ['id' => 9999], [], $resolveInfo);
        
        $this->assertNull($result);
    }
}

这种方式直接测试核心业务逻辑,不需要启动整个HTTP服务,测试效率拉满。

2. 测试完整GraphQL请求链路

如果你想覆盖Schema验证、参数校验等全链路场景,用PHPUnit发送GraphQL请求也是不错的选择,甚至可以借助Laravel GraphQL常用包(比如rebing/graphql-laravel)的辅助能力简化代码。

比如这样写:

use Tests\TestCase;

class ClientQueryGraphQLTest extends TestCase
{
    public function test_client_query_with_valid_id()
    {
        $client = Client::factory()->create();
        
        // 发送GraphQL查询请求
        $response = $this->postJson('/graphql', [
            'query' => '
                query GetClient($id: Int!) {
                    client(id: $id) {
                        id
                        name
                        email
                    }
                }
            ',
            'variables' => [
                'id' => $client->id
            ]
        ]);
        
        // 断言响应正确
        $response->assertStatus(200)
                 ->assertJson([
                     'data' => [
                         'client' => [
                             'id' => $client->id,
                             'name' => $client->name,
                             'email' => $client->email
                         ]
                     ]
                 ]);
    }
    
    public function test_client_query_with_invalid_id_type()
    {
        $response = $this->postJson('/graphql', [
            'query' => '
                query GetClient($id: Int!) {
                    client(id: $id) {
                        id
                    }
                }
            ',
            'variables' => [
                'id' => 'not-a-number' // 传入不符合类型的参数
            ]
        ]);
        
        // 断言返回参数错误提示
        $response->assertStatus(200)
                 ->assertJsonStructure([
                     'errors' => [
                         '*' => [
                             'message',
                             'locations'
                         ]
                     ]
                 ]);
    }
}

这种方式能确保你的GraphQL API对外表现完全符合预期,覆盖参数校验、类型转换等边界场景。

3. 测试Query的定义规范

除了业务逻辑,你还可以测试Query的args和type方法,确保参数定义和返回类型完全符合你的Schema设计:

use Tests\TestCase;
use App\GraphQL\Queries\ClientQuery;
use GraphQL\Type\Definition\Type;

class ClientQueryDefinitionTest extends TestCase
{
    public function test_query_has_correct_attributes()
    {
        $query = new ClientQuery();
        
        $this->assertEquals('ClientQuery', $query->attributes['name']);
        $this->assertEquals('A query', $query->attributes['description']);
    }
    
    public function test_query_args_are_correct()
    {
        $query = new ClientQuery();
        $args = $query->args();
        
        // 断言id参数是必填的Int类型
        $this->assertArrayHasKey('id', $args);
        $this->assertEquals(Type::nonNull(Type::int()), $args['id']['type']);
    }
    
    public function test_query_returns_correct_type()
    {
        $query = new ClientQuery();
        $type = $query->type();
        
        // 断言返回的是Client类型
        $this->assertEquals('Client', $type->name);
    }
}

这种测试能避免出现参数类型错误、返回类型不匹配这类低级但影响很大的问题。

总结一下

  • 想快速测试核心业务逻辑?直接测试Resolver是最优选择,速度快且聚焦;
  • 要验证API全链路行为?发送GraphQL请求测试端点能覆盖更多场景;
  • 额外的定义测试可以确保你的Query完全符合Schema规范,提前规避潜在问题。

根据你的需求组合这些方案,就能全面覆盖你的GraphQL应用测试啦!

内容的提问来源于stack exchange,提问作者Vandemberg Lima

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 06:58:48