reactjs - ReactJS Jest Tesing - fireEvent.click() 没有触发按钮
问题描述
我人生中第一次做测试。我有一个秒表应用程序,我想检查测试是否正在运行。我通过触发按钮来做到这一点,并检查 00:00:00 是否仍然存在。
问题是那些 00:00:00 在触发按钮后仍处于跨度中。程序运行正常,完全没有问题。这个triggerin的问题在哪里?
我有一个按钮START
:
class SecondTimer extends React.Component {
constructor(props) {
super(props);
this.state = {
running: false, // Format to false, so when start a program clock is not running
currentTimeMs: 0,
currentTimeSec: 0,
currentTimeMin: 0,
};
}
start = () => {
if (!this.state.running) {
this.setState({ running: true });
this.watch = setInterval(() => this.pace(), 10);
}
};
{this.state.running === false && (
<Button className={"start-stop-reset-nappi"} variant="success" size="lg" onClick=
{this.start}>START</Button>
)}
我有span
时间显示(开始前的值是 00:00:00,下图)。
<span>
{this.props.formatTime(this.props.currentTimeMin)}:
{this.props.formatTime(this.props.currentTimeSec)}:
{this.props.formatTime(this.props.currentTimeMs)}
</span>
然后我有这个测试:
import { render, screen, fireEvent } from '@testing-library/react';
import SecondTimer from '../components/SecondTimer.jsx';
test('Test - Secondmeter running or not', () => {
render(<SecondTimer />);
const start = screen.getByText("START") // Here I'll check is there button (text) like START
fireEvent.click(start); // Then I "Click" it
const numbers = screen.getByText(/00:00:00/i) // Check is the 00:00:00 still on screen after triggering the button
expect(numbers).toBeInTheDocument()
});
完整的组件代码:
import React from 'react';
import SecondTimerNumbers from './SecondTimerNumbers.jsx';
import SecondTimerList from './SecondTimerList.jsx';
import { Button } from 'react-bootstrap';
import 'bootstrap/dist/css/bootstrap.min.css';
class SecondTimer extends React.Component {
constructor(props) {
super(props);
// Start funktio määrittää running arvon -> true, joka kertoo sen, että kello käy. Tallentaa tänne ajan, josta SeconTimerNumber hakee tiedon
this.state = {
running: false, // Alustettu falseksi, eli ohjelman avatessa kello ei käy
currentTimeMs: 0,
currentTimeSec: 0,
currentTimeMin: 0,
};
}
// Muuttaa kelloajan numeraaliset luvut stringiksi, sekä lisää yhdet nollat lukuun, jotta luvut ei ns. pompi silmillä.
formatTime = (val, ...rest) => {
let value = val.toString();
if (value.length < 2) {
value = '0' + value;
}
if (rest[0] === 'ms' && value.length < 3) {
value = '0' + value;
}
return value;
};
// Start napista painalla käynnistää tämän funktion. Muuttaa state running trueksi, eli kello käy. SetInterval on Reactin oma sekuntikello, ja this.pace 10 määrittelee sadasosasekunnit
start = () => {
if (!this.state.running) {
this.setState({ running: true });
this.watch = setInterval(() => this.pace(), 10);
}
};
// Stop painikkeesta muuttaa running staten falseksi -> kello pysähtyy, sekä tyhjentää sekuntikellon (pysäyttää).
stop = () => {
this.setState({ running: false });
clearInterval(this.watch);
};
// Määrittelee kellon toiminnan
pace = () => {
this.setState({ currentTimeMs: this.state.currentTimeMs + 10 }); // Lisää 10ms kerrallaan
// Kun millisekunteja 1000, lisää yhden sekunnin, sekä muuttaa millisekuntien arvoksi 0 kierroksen jälkeen
if (this.state.currentTimeMs >= 1000) {
this.setState({ currentTimeSec: this.state.currentTimeSec + 1 });
this.setState({ currentTimeMs: 0 });
}
// Kun sekunteja on 60, lisää yhden minuutin, sekä muuttaa sekuntien arvoksi 0 kierroksen jälkeen
if (this.state.currentTimeSec >= 60) {
this.setState({ currentTimeMin: this.state.currentTimeMin + 1 });
this.setState({ currentTimeSec: 0 });
}
};
// Määrittää (resetoi) staten allaolevat arvot nollaksi, jolloin sekuntikello voidaan taas aloittaa alusta
resetTime = () => {
this.setState({
currentTimeMs: 0,
currentTimeSec: 0,
currentTimeMin: 0,
});
};
// UserInterface eli käyttöliittymä renderöityy tässä
render() {
return (
<div className={'main-div'}>
<div className={'left'}>
{this.state.running === false && (
<Button className={"start-stop-reset-nappi"} variant="success" size="lg" onClick={this.start}>START</Button>
)}
{this.state.running === true && (
<Button className={'start-stop-reset-nappi'} variant="warning" size="lg" onClick={this.stop}>PAUSE</Button>
)}
<Button className={'start-stop-reset-nappi'} variant="danger" size="lg" onClick={this.resetTime}>RESET</Button>
<div className={'tulostaulu-main'}>
<SecondTimerNumbers
ref="display"
{...this.state}
formatTime={this.formatTime}
/>
</div>
</div>
<div className={'right'}>
<SecondTimerList clickResetTime={this.resetTime} {...this.state} formatTime={this.formatTime} />
</div>
</div>
);// Yllä oleva ClickResetTime funktio on tämän sivut resetTime funktio.
// Tällä saan kutsuttua funktiota toisesta componentista, tavallaan "injektoin" funktion tähän componenttiin.
}
}
export default SecondTimer;
解决方案
我真的不知道你的测试有什么问题。我根据您当前的测试创建了一个小测试,效果非常好。
测试的想法很简单。当我点击按钮时,我希望能在几秒钟内看到变化。关键是使用waitFor
带有指定timeout
选项的 api 来确保测试库解决您的 UI 更改。
这是片段:
import React from "react";
import { render, screen, fireEvent, waitFor } from "@testing-library/react";
import "@testing-library/jest-dom";
import { SecondTimer } from "./App";
test("should work", async () => {
render(<SecondTimer />);
const start = screen.getByText("START");
fireEvent.click(start);
await waitFor(() => screen.getByText(/00:02:00/i), {
timeout: 2000 // wait 2s
});
const numbers = screen.getByText(/00:02:00/i);
expect(numbers).toBeInTheDocument();
});
这是我专门为您创建的代码框(使测试能够运行的设置基于create-react-app
脚本):
https://codesandbox.io/s/morning-browser-92uks?file=/src/App.test.js
注意:要运行测试,请单击预览区域Tests
旁边的选项卡Browser
推荐阅读
- vue.js - 从 vue.js 生成文件下载
- r - 多个文件中变量之间的相关性
- javascript - 如何为使用 React 钩子的 Apollo 查询创建包装器
- html - 下拉选项不随选择框移动
- python-3.x - Python:检查元组是否仅包含带有while的整数
- scheme - 如何在Scheme中将十进制转换为十六进制?(需要在 GIMP 中将 RGB 转换为 HEX)
- sql - 在 SQL 查询方面需要一些帮助
- python - Keras 上的自定义损失函数
- elasticsearch - Elasticsearch:elasticsearch.service 的作业失败
- android - 错误构建gradle