无法从jest中的react组件触发回调函数

58wvjzkj  于 2022-12-08  发布在  Jest
关注(0)|答案(1)|浏览(177)

我正在尝试为一个简单的天气Web应用编写一些jest测试,这个应用是我用React开发的。当我运行测试时,它创建了一个组件的快照,看起来不错,但是当我尝试触发一个click事件时,我得到了一个类型错误:

TypeError: tree.props.handleClick is not a function

我使用jest docs来编写这个测试,我认为这就是你触发点击事件的方式。我没有正确引用点击函数吗?我是第一次编写测试,所以欢迎提供任何关于编写React with jest测试的信息!

React代码

import React from "react"
import { useEffect, useState } from 'react'
// import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'

const CityEntry = ({ weatherDatum, deleteLocation }) => {
  const capitalizeFirstLetter = (string) => {
    return string.charAt(0).toUpperCase() + string.slice(1);
  }

  const handleClick= () => {
    deleteLocation(weatherDatum.id)
  }

  return (
    <div className="city">
      <p className="location flex-item">{capitalizeFirstLetter(weatherDatum.location)} </p>
      <p className="temp flex-item">{weatherDatum.temperature}  &#x2109;</p>
      <p className="feels-like flex-item">Feels like: {weatherDatum.feelsLike}</p>
      <p className="description flex-item">{capitalizeFirstLetter(weatherDatum.description)}</p>
      <p><img className="icon flex-item" src={`https://openweathermap.org/img/w/${weatherDatum.icon}.png`}></img></p>
      <button className="delete" onClick={handleClick}>Delete</button>
    </div>
  )
}

export default CityEntry;

Jest测试代码

import renderer from 'react-test-renderer';
import CityEntry from '../src/Components/CityEntry.js'

it('deletes a city entry when clicked', () => {
  const component = renderer.create(
    <CityEntry weatherDatum={{ id: '', lat: '', lon: '', location: '', temperature: '', feelsLike: '', description: '', icon: '' }} />
  );
  let tree = component.toJSON();
  expect(tree).toMatchSnapshot()

  renderer.act(() => {
    tree.props.handleClick()
  });

  tree = component.toJSON();
  expect(tree).toMatchSnapshot()
})

创建的Jest快照

exports[`deletes a city entry when clicked 1`] = `
<div
  className="city"
>
  <p
    className="location flex-item"
  >
     
  </p>
  <p
    className="temp flex-item"
  >
      ℉
  </p>
  <p
    className="feels-like flex-item"
  >
    Feels like: 
  </p>
  <p
    className="description flex-item"
  />
  <p>
    <img
      className="icon flex-item"
      src="https://openweathermap.org/img/w/.png"
    />
  </p>
  <button
    className="delete"
    onClick={[Function]}
  >
    Delete
  </button>
</div>
`;
oyxsuwqo

oyxsuwqo1#

组件的JSON表示只能用于Assert,不能用来操作组件的状态,JSON不能包含函数,它只是静态数据。
要模拟按钮单击,您需要使用TestInstance上可用的方法。
最好触发按钮上的实际单击处理程序,以便调用另一个deleteLocation函数。

import renderer from 'react-test-renderer';
import CityEntry from '../src/Components/CityEntry.js'

it('deletes a city entry when clicked', () => {
  const component = renderer.create(
    <CityEntry weatherDatum={{ id: '', lat: '', lon: '', location: '', temperature: '', feelsLike: '', description: '', icon: '' }} />
  );
  let tree = component.toJSON();
  expect(tree).toMatchSnapshot()

  renderer.act(() => {
    component.root.findByType('button').props.onClick();
  });

  tree = component.toJSON();
  expect(tree).toMatchSnapshot()
})

顺便说一句,你可以考虑使用React Testing Libraryreact-test-renderer API的级别非常低,大多数人觉得这更符合人体工程学。我看到最近创建的大多数React测试套件都是沿着这条路走的。
从哲学上讲,它也阻止了你将要做的事情,那就是抓住 prop 并直接操纵它们,这是因为好的测试只会像真实的的用户那样与元素交互。

相关问题