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";
}
}));
我的测试有一个错误,将 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";
}
}));