我使用 React 查询从 Next.js 路由处理程序获取硬编码数据,但我的自定义挂钩返回未定义。
我的自定义挂钩在我的组件中工作正常,但在测试文件中返回未定义。
//route.ts
export async function GET() {
const data = [
{
title: "product one",
price: 1200,
},
{
title: "product two",
price: 1200,
}
];
return Response.json(data);
}
//page.test.ts
test("isSuccess", async () => {
const { result } = renderHook(() => useGetListingDataHook(), {
wrapper: ReactQueryProvider,
});
await waitFor(() => expect(result.current.isSuccess).toBe(true));
});
问题:useGetListingDataHook 在我的测试中返回未定义,但在组件中工作正常。
问题:
您的自定义 React Query 钩子似乎在组件中正常工作,但在测试中返回未定义。发生此问题通常是因为您的钩子发出的 API 请求在测试环境中未正确模拟,并且测试是独立运行的,无法访问实际的 API 路由。
解决方案:
要解决此问题,您可以在测试中模拟 API 响应。我建议使用 msw(Mock Service Worker)来处理测试中的 API 模拟。它与 React Query 配合良好,可以轻松模拟 HTTP 请求
步骤:
如果您还没有安装msw:
npm install msw --save-dev
在测试文件中设置模拟 API 响应:
以下是如何使用 msw 模拟 GET 请求并修复测试的示例:
// page.test.ts
import { renderHook } from '@testing-library/react-hooks';
import { waitFor } from '@testing-library/react';
import { useGetListingDataHook } from 'path-to-your-hook'; // Adjust the import path
import { setupServer } from 'msw/node';
import { rest } from 'msw';
import ReactQueryProvider from 'path-to-your-provider'; // Import your react-query provider
// Mock the API response
const server = setupServer(
rest.get('/api/your-route', (req, res, ctx) => {
return res(
ctx.json([
{ title: 'product one', price: 1200 },
{ title: 'product two', price: 1200 },
])
);
})
);
// Start the server before all tests and stop it after all tests
beforeAll(() => server.listen());
afterEach(() => server.resetHandlers());
afterAll(() => server.close());
test('isSuccess', async () => {
const { result } = renderHook(() => useGetListingDataHook(), {
wrapper: ReactQueryProvider, // You need to wrap with your react-query provider
});
await waitFor(() => expect(result.current.isSuccess).toBe(true));
});
解释:
模拟 API 请求:您使用 msw 来模拟您的 API。 setupServer 函数创建一个模拟服务器,rest.get 模拟您的钩子对 /api/your-route 端点发出的 GET 请求。
测试生命周期管理:服务器使用 beforeAll 启动,并在所有测试后使用 afterAll 停止。 resetHandlers 确保模拟服务器在测试之间重置,防止数据过时。
此设置应允许您的自定义挂钩在测试期间返回预期数据。