首页 > 解决方案 > 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;

标签: reactjsreact-testing-library

解决方案


我真的不知道你的测试有什么问题。我根据您当前的测试创建了一个小测试,效果非常好。

测试的想法很简单。当我点击按钮时,我希望能在几秒钟内看到变化。关键是使用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


推荐阅读