React / Jest 设置测试以定义 Windows 对象

Sol*_*ole 6 javascript reactjs jestjs

我的测试中出现错误,将窗口环境变量标记为未定义。我理解该错误,因为它是基于使用变量的应用程序的运行时,并且可能它们在运行应用程序时未定义。但我不知道 setupTests.tsx 中的哪个位置需要定义它。到目前为止,该变量的使用方式如下:

\n

索引.html

\n
<!DOCTYPE html>\n<html lang="en">\n  <head>\n    <meta charset="utf-8" />\n    <link rel="icon" href="%PUBLIC_URL%/favicon.ico" />\n    <meta name="viewport" content="width=device-width, initial-scale=1" />\n    <script src="%PUBLIC_URL%/config.js"></script>\n  </head>\n  <body>\n    <noscript>You need to enable JavaScript to run this app.</noscript>\n    <div id="root"></div>\n  </body>\n</html>\n
Run Code Online (Sandbox Code Playgroud)\n

配置文件

\n
window._env_ = {\n  REACT_APP_URL: "https://apiurl.com"\n}\n
Run Code Online (Sandbox Code Playgroud)\n

如何在应用程序中使用它:

\n
declare const window: Window &\n    typeof globalThis & {\n        _env_: any\n    }\n\nconst url = window._env_.REACT_APP_URL;\nexport const apiUrl = url;\n
Run Code Online (Sandbox Code Playgroud)\n

setupTests.tsx我确实尝试将其添加到此处,但它仍然无法正常工作

\n
import '@testing-library/jest-dom';\nimport { setLogger } from 'react-query'\nimport { server } from './mocks/server'\ndeclare const window: Window &\n\ntypeof globalThis & {\n    _env_: any\n}\n\nwindow._env_.REACT_APP_URL = "https://wwww.xxxxx.com"\n\nbeforeAll(() => server.listen())\n// Reset any request handlers that we may add during the tests,\n// so they don't affect other tests.\n\n\nafterEach(() => server.resetHandlers())\n\n// Clean up after the tests are finished.\nafterAll(() => server.close())\n
Run Code Online (Sandbox Code Playgroud)\n

停止测试的错误:

\n
  \xe2\x97\x8f Test suite failed to run\n\n    TypeError: Cannot read properties of undefined (reading 'REACT_APP_URL')\n\n      4 |     }\n      5 |\n    > 6 | const url = window._env_.REACT_APP_URL;\n        |                          ^\n      7 | export const apiUrl = url;\n      8 |\n      9 |\n  at Object.<anonymous> (src/utils/Url.tsx:6:26)\n  at Object.<anonymous> (src/mocks/handlers.tsx:3:1)\n  at Object.<anonymous> (src/mocks/server.tsx:2:1)\n  at Object.<anonymous> (src/setupTests.tsx:7:1)\n
Run Code Online (Sandbox Code Playgroud)\n

Ovi*_*nas 3

您看到错误的原因:新的 create-react-app 项目自动附带的库jest已经预先配置为jsdom作为测试环境(ref)使用,这意味着该window属性将在运行时定义你的测试。但是,_env_不是window变量的默认属性,这意味着它是undefined,并且尝试访问其属性将会给您带来错误。这个问题可以通过为属性分配一个新对象来解决_env_,但是还有另一个问题阻碍了我们——const url = window._env_.REACT_APP_URL;在执行测试之前总是会评估以下分配。原因是因为当一个文件(在本例中setupTests.tsx)导入另一个文件(例如Url.tsx)时,导入文件的逻辑会立即评估(几乎就像触发隐式调用的函数),并且其中的任何变量赋值都会立即执行,从而覆盖_env_您的测试中的属性将不起作用,因为为时已晚。

要解决此问题:您可以模拟包含变量的整个文件,并使用以下代码(应放置在测试文件的顶部)让它返回您需要的内容:

jest.mock('./src/utils/Url', () => ({
  get apiUrl () {
    return "https://wwww.xxxxx.com";
  }
}));
Run Code Online (Sandbox Code Playgroud)