Next.js中基于tRPC的组件测试配置及查询模拟方案问询
解决tRPC Next.js组件测试的环境配置与查询模拟问题
核心思路
测试时无需运行真实服务端,只需在测试代码中搭建tRPC的客户端上下文,同时模拟useQuery的返回数据,让组件能正常获取所需状态。
步骤1:创建测试专用的tRPC Provider包装组件
写一个能在测试环境注入模拟客户端的Provider组件,替代项目中原本的tRPC Provider:
// test-utils/trpc-provider.tsx import { createTRPCReact } from '@trpc/react-query'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { ReactNode } from 'react'; import { type AppRouter } from '../server/routers/_app'; export const trpc = createTRPCReact<AppRouter>(); export function MockTRPCProvider({ children, mockClient }: { children: ReactNode; mockClient: ReturnType<typeof trpc.createClient> }) { const queryClient = new QueryClient(); return ( <trpc.Provider client={mockClient} queryClient={queryClient}> <QueryClientProvider client={queryClient}> {children} </QueryClientProvider> </trpc.Provider> ); }
步骤2:模拟tRPC客户端与查询方法
用jest(或你使用的测试框架)模拟tRPC客户端,让useQuery返回预设的测试数据:
// SampleComponent.test.tsx import { render, screen } from '@testing-library/react'; import SampleComponent from './SampleComponent'; import { MockTRPCProvider, trpc } from '../test-utils/trpc-provider'; import { type AppRouter } from '../server/routers/_app'; describe('SampleComponent', () => { it('renders data from tRPC query', async () => { // 模拟客户端实例 const mockClient = trpc.createClient({ url: '/api/trpc', }) as jest.Mocked<ReturnType<typeof trpc.createClient>>; // 针对目标路由,模拟返回测试数据 mockClient.sampleRoute.query.mockResolvedValue({ id: 1, name: 'Mocked Data', }); render( <MockTRPCProvider mockClient={mockClient}> <SampleComponent /> </MockTRPCProvider> ); // 断言组件渲染了模拟数据 const dataElement = await screen.findByText('Mocked Data'); expect(dataElement).toBeInTheDocument(); }); });
步骤3:简化重复配置(可选)
如果多个测试都需要用到这个Provider,可以封装成测试专用的render函数:
// test-utils/render.tsx import { render as rtlRender, RenderOptions } from '@testing-library/react'; import { ReactNode } from 'react'; import { MockTRPCProvider, trpc } from './trpc-provider'; export function render( ui: ReactNode, options?: { mockClient?: ReturnType<typeof trpc.createClient> } & RenderOptions ) { const mockClient = options?.mockClient || (trpc.createClient({ url: '/api/trpc' }) as jest.Mocked<ReturnType<typeof trpc.createClient>>); return rtlRender( <MockTRPCProvider mockClient={mockClient}> {ui} </MockTRPCProvider>, options ); }
后续测试时直接调用这个封装好的render函数即可,无需重复编写Provider代码。
关键注意点
- 确保模拟的客户端类型与项目中真实的
AppRouter类型一致,避免类型错误。 - 如果组件用到
tRPC的其他方法(如useMutation),需在mockClient中同步模拟对应方法的返回(比如mockResolvedValue或mockRejectedValue)。 - 测试异步组件时,必须使用
await findBy*这类异步查询方法,等待数据加载完成后再执行断言。
内容的提问来源于stack exchange,提问作者Christian Ivicevic
相关产品推荐
相关产品推荐

