如何在Apollo Server集成测试中复用.gql文件中的Fragments?
在Apollo集成测试中复用客户端共享的GraphQL片段
当然有可行方案,核心思路就是把.gql文件里的片段和测试用的查询组合成完整的GraphQL文档,传给executeOperation就行——毕竟Apollo执行查询时只关心最终的完整DocumentNode,不需要片段提前在服务器Schema里定义。
下面是几个实用的实现方式:
1. 直接导入片段并拼接查询
用graphql-tag的gql模板字符串直接导入客户端的.gql片段,然后在测试查询里引用,最后把两者拼接成一个完整的查询文档:
import { gql } from 'apollo-server'; // 导入客户端共享的片段文件 import userProfileFragment from '../client/fragments/userProfile.gql'; // 编写测试用查询,引用片段 const getUserTestQuery = gql` query GetUserTest($userId: ID!) { user(id: $userId) { ...UserProfileFields } } ${userProfileFragment} // 把片段拼接到查询后面 `; // 传入executeOperation执行 test('fetch user with shared fragment', async () => { const server = getTestApolloServer(); const result = await server.executeOperation({ query: getUserTestQuery, variables: { userId: '123' } }); // 断言结果... });
这种方式最直接,完全复用客户端的片段文件,零重复代码。
2. 封装复用的查询模块
如果多个测试都要用到带片段的查询,可以专门建一个测试工具模块,把组合好的查询提前封装好:
// test/utils/gqlQueries.js import { gql } from 'apollo-server'; import userProfileFragment from '../../client/fragments/userProfile.gql'; export const getUserWithProfile = gql` query GetUser($userId: ID!) { user(id: $userId) { ...UserProfileFields } } ${userProfileFragment} `;
然后在测试文件里直接导入使用:
import { getUserWithProfile } from './utils/gqlQueries'; test('...', async () => { const result = await server.executeOperation({ query: getUserWithProfile, variables: { userId: '123' } }); });
3. 批量注册片段(适用于多片段场景)
如果要复用大量片段,可以把所有共享片段打包成一个DocumentNode集合,在测试前统一拼接:
import { gql } from 'apollo-server'; import userFragment from '../client/fragments/user.gql'; import postFragment from '../client/fragments/post.gql'; // 把所有片段合并成一个文档 const sharedFragments = gql` ${userFragment} ${postFragment} `; // 测试查询时,把查询和共享片段拼接 const getPostWithAuthorQuery = gql` query GetPost($postId: ID!) { post(id: $postId) { ...PostFields author { ...UserFields } } } ${sharedFragments} `;
核心原理就是:只要最终传给executeOperation的是包含所有引用片段的完整GraphQL文档,Apollo就能正常解析执行,和客户端使用片段的逻辑完全一致,不需要修改服务器Schema。
内容的提问来源于stack exchange,提问作者Christopher Simmons
相关产品推荐
相关产品推荐

