ReferenceError:使用 React Router v6.4 测试时未定义请求

The*_*lie 14 typescript react-router react-testing-library

我正在尝试使用 React 测试库创建单元测试,单击 React Router 链接来验证某些页面的显示。我使用的设置与此处找到的答案非常相似。当我运行测试时,我得到了ReferenceError: Request is not defined. 由于我使用的是 RouterProvider,我无法完全遵循 React 测试库文档。

\n

我在专用文件中设置了路线:

\n
export const routes: RouteObject[] = [{\n    path: \'/\',\n    element: <AppWrapper />,\n    errorElement: <PageNotFoundScreen />,\n    children: [{\n        path: \'/\',\n        element: <FeaturedSearchScreen />\n    },{\n        path: \'auth\',\n        element: <AuthScreen />,\n        children: [{\n            path: \'login\',\n            element: <LoginForm />\n        },{\n            path: \'signup\',\n            element: <SignUpForm />\n        }]\n        },{\n            path: \'dashboard\',\n            element: <DashboardScreen />\n        },{\n            path: \'search\',\n            element: <SearchResultsScreen />,\n            loader: searchLoader\n        } \n    ]\n}];\n
Run Code Online (Sandbox Code Playgroud)\n

然后我在测试文件中创建一个内存路由器

\n
const router = createMemoryRouter(routes, {initialEntries: [\'/\']});\nconst user = userEvent.setup();\nrender(<RouterProvider router={router}/>);\n
Run Code Online (Sandbox Code Playgroud)\n

我正在 AppWrapper 中使用 Outlet 来渲染所有子项。

\n

预期的

\n

测试通过

\n

结果

\n
Vitest caught 1 unhandled error during the test run.\nThis might cause false positive tests. Resolve unhandled errors to make sure your tests are not affected.\n\n\xe2\x8e\xaf\xe2\x8e\xaf\xe2\x8e\xaf\xe2\x8e\xaf Unhandled Rejection \xe2\x8e\xaf\xe2\x8e\xaf\xe2\x8e\xaf\xe2\x8e\xaf\xe2\x8e\xaf\nReferenceError: Request is not defined\n \xe2\x9d\xaf createRequest node_modules/@remix-run/router/router.ts:2654:3\n \xe2\x9d\xaf startNavigation node_modules/@remix-run/router/router.ts:886:19\n \xe2\x9d\xaf Object.navigate node_modules/@remix-run/router/router.ts:784:18\n \xe2\x9d\xaf push node_modules/react-router/lib/components.tsx:74:16\n \xe2\x9d\xaf navigate node_modules/react-router/lib/hooks.tsx:211:7\n \xe2\x9d\xaf internalOnClick node_modules/react-router-dom/index.tsx:727:9\n \xe2\x9d\xaf handleClick node_modules/react-router-dom/index.tsx:385:9\n \xe2\x9d\xaf HTMLUnknownElement.callCallback node_modules/react-dom/cjs/react-dom.development.js:4164:14\n \xe2\x9d\xaf HTMLUnknownElement.callTheUserObjectsOperation node_modules/jsdom/lib/jsdom/living/generated/EventListener.js:26:30\n \xe2\x9d\xaf innerInvokeEventListeners node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:350:25\n
Run Code Online (Sandbox Code Playgroud)\n

当我渲染初始屏幕时,我能够验证所有组件,因此我知道我的设置通常正常工作。它无法等待新的页眉。请随意查看此分支上的完整代码https://github.com/Thenlie/Streamability/tree/43-feat-test-suite

\n

小智 14

我使用“jest-fetch-mock”解决了这个问题(https://www.npmjs.com/package/jest-fetch-mock

对于 TypeScript/ES6,将以下行添加到文件中测试用例的开头(在任何其他导入之前)setupTests.ts

import { enableFetchMocks } from 'jest-fetch-mock'
enableFetchMocks();
Run Code Online (Sandbox Code Playgroud)


The*_*lie 7

我最终需要创建一个定义 Request 的安装文件。我通过React Router 代码找到了这个

import { fetch, Request, Response } from "@remix-run/web-fetch";

if (!globalThis.fetch) {
  // Built-in lib.dom.d.ts expects `fetch(Request | string, ...)` but the web
  // fetch API allows a URL so @remix-run/web-fetch defines
  // `fetch(string | URL | Request, ...)`
  // @ts-expect-error
  globalThis.fetch = fetch;
  // Same as above, lib.dom.d.ts doesn't allow a URL to the Request constructor
  // @ts-expect-error
  globalThis.Request = Request;
  // web-std/fetch Response does not currently implement Response.error()
  // @ts-expect-error
  globalThis.Response = Response;
}
Run Code Online (Sandbox Code Playgroud)

然后可以在我的测试配置文件中引用它vitest.config.ts

import { defineConfig } from 'vitest/config';

// https://vitest.dev/guide/#configuring-vitest
export default defineConfig({
    test: {
        environment: 'jsdom',
        setupFiles: './src/__tests__/setup.ts',
        globals: true,
        watch: false
    }
});
Run Code Online (Sandbox Code Playgroud)