React / Jest setUp 测试具有定义的 windows 对象

React / Jest setUp tests to have windows object as defined

我的测试有一个错误,将 window 环境变量标记为未定义。我理解这个错误,因为它是基于使用变量的应用程序的运行时,也许它们在 运行 应用程序上未定义。但是我不知道在 setupTests.tsx 的什么地方,我需要定义它。到目前为止,变量是这样使用的:

index.html

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

config.js

window._env_ = {
  REACT_APP_URL: "https://apiurl.com"
}

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

declare const window: Window &
    typeof globalThis & {
        _env_: any
    }

const url = window._env_.REACT_APP_URL;
export const apiUrl = url;

setupTests.tsx 我试过在这里添加它,但还是不行

import '@testing-library/jest-dom';
import { setLogger } from 'react-query'
import { server } from './mocks/server'
declare const window: Window &

typeof globalThis & {
    _env_: any
}

window._env_.REACT_APP_URL = "https://wwww.xxxxx.com"

beforeAll(() => server.listen())
// Reset any request handlers that we may add during the tests,
// so they don't affect other tests.


afterEach(() => server.resetHandlers())

// Clean up after the tests are finished.
afterAll(() => server.close())

停止测试的错误:

  ● Test suite failed to run

    TypeError: Cannot read properties of undefined (reading 'REACT_APP_URL')

      4 |     }
      5 |
    > 6 | const url = window._env_.REACT_APP_URL;
        |                          ^
      7 | export const apiUrl = url;
      8 |
      9 |
  at Object.<anonymous> (src/utils/Url.tsx:6:26)
  at Object.<anonymous> (src/mocks/handlers.tsx:3:1)
  at Object.<anonymous> (src/mocks/server.tsx:2:1)
  at Object.<anonymous> (src/setupTests.tsx:7:1)

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

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

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