React Test-组件访问窗口对象时错误
由于特定原因,我在index.html
文件中使用脚本 public 文件夹中,此脚本在window> window
对象上创建属性。该属性是异步函数。这是我在public/index.html中创建的脚本:
<script>
const txt = "Hello Word";
async function waitText() {
try {
const data = await fetch(
"https://jsonplaceholder.typicode.com/all/1"
);
const text = await data.json();
returntext;
} catch (error) {
console.error(error);
return "Error";
}
}
Object.defineProperty(window, "waitText", { value: waitText });
</script>
我的应用程序组件首先渲染加载...在USESTATE中指定的文本,然后在使用效果中的异步函数调用Windom对象的功能,等待响应并执行响应固定状态并更改加载...文本为从API获得的文本。到目前为止,该应用程序毫无问题地工作。在这里,app.tsx的代码
import logo from "./logo.svg";
import "./App.css";
import { useEffect, useState } from "react";
function App() {
const [txt, setTxt] = useState("Loading...");
useEffect(() => {
const getTxt = async() => {
try {
const text = await window.waitText();
setTxt(text.title);
} catch (error) {
console.error(error);
}
};
getTxt();
}, []);
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>{txt}</p>
</header>
</div>
);
}
export defaultApp;
到目前为止,应用程序正常运行。问题是用开玩笑和反应测试图表进行测试。在这里,文本的代码:
import { render, screen } from '@testing-library/react';
import App from './App';
test('renders learn react link', async () => {
render(<App />);
screen.debug()
const linkElement = await screen.findByText("delectus aut autem");
expect(linkElement).toBeInTheDocument();
});
运行此测试时,在呼叫window.waittext()时专门在使用效率区域中引起错误。显然,当执行嘲笑测试时,它不会执行索引中的脚本。
从public/index.html中删除脚本不是解决方案。很好,尽管这不是一个好的做法,但在某些情况下,有必要这样做。
创建反应的文档对此表示了:
无论如何,如何使该组件通过测试?
For a specific reason I use a script in the index.html
file in the public
folder, this script creates a property on the window
object. The property is an asynchronous function. here is the script i created in public/index.html:
<script>
const txt = "Hello Word";
async function waitText() {
try {
const data = await fetch(
"https://jsonplaceholder.typicode.com/all/1"
);
const text = await data.json();
returntext;
} catch (error) {
console.error(error);
return "Error";
}
}
Object.defineProperty(window, "waitText", { value: waitText });
</script>
My App component starts by rendering a Loading... text specified in a useState, then an asynchronous function in useEffect calls the function of the windom object, waits for the response and does the setState and changes the Loading... text to the one it got from the api. So far the app works without problems. Here the code of App.tsx
import logo from "./logo.svg";
import "./App.css";
import { useEffect, useState } from "react";
function App() {
const [txt, setTxt] = useState("Loading...");
useEffect(() => {
const getTxt = async() => {
try {
const text = await window.waitText();
setTxt(text.title);
} catch (error) {
console.error(error);
}
};
getTxt();
}, []);
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>{txt}</p>
</header>
</div>
);
}
export defaultApp;
Up to this point the app works fine. The problem is to do the test with jest and react-testing-library. Here the code of the text:
import { render, screen } from '@testing-library/react';
import App from './App';
test('renders learn react link', async () => {
render(<App />);
screen.debug()
const linkElement = await screen.findByText("delectus aut autem");
expect(linkElement).toBeInTheDocument();
});
When running this test, an error is raised in the useEffect area specifically when calling window.waitText(). Apparently when executing the jest test it does not execute the script that is in the index.html and therefore the property is never created in the window object, consequently an error arises in the useEffect and the text does not work.
Removing the script from public/index.html is not a solution. Well, although it is not a good practice, there are certain cases in which it is necessary to do so.
The create-react-app documentation says about this:
Some libraries may be incompatible with webpack and you have no choice but to include it as a tag.
Anyway, how to make this component pass the test?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您可以模拟
window.waittext()
方法及其在测试案例中呈现组件之前的解决/拒绝值。例如
app.jsx
:app.test.jsx
:测试结果:
You can mock the
window.waitText()
method and its resolve/rejected value before rendering the component in the test case.E.g.
App.jsx
:App.test.jsx
:Test result: