【问题标题】:TypeError: Cannot read property 'map' of undefined (jest.js)TypeError:无法读取未定义的属性“地图”(jest.js)
【发布时间】:2019-10-05 03:01:15
【问题描述】:

我有一个包含输入和按钮的组件。当用户在输入中键入爱好时,假设将该字符串发送到 API 进行更新。我已经设置了我的测试并且我正在测试组件是否存在并且我收到错误 TypeError: Cannot read property 'map' of undefined, 当我 console.log(component)。它表示组件未定义。

当我注释掉 {this.state.hobbies.map()} 部分(包括第二个渲染和其中的所有内容)时,组件能够渲染。

    EditProfile.js
    import React, { Component } from 'react';
    import { MdDelete } from 'react-icons/md';
    import { updateHobbies } from '../../services/updateHobbies';
    import './edit_profile.scss';
    import PropTypes from 'prop-types';

    class EditProfile extends Component {
      state = {
        hobbies: this.props.employeeHobbies,
        userInput: ''
      };

      handleChange = e => {
        this.setState({ userInput: e.target.value });
      };

      handleButtonClick = () => {
        const hobby = this.state.hobbies.concat(this.state.userInput);
        this.setState({ hobbies: hobby, userInput: '' }, () => 
       updateHobbies(this.state.hobbies));
      };

      handleDelete = e => {
        const array = [...this.state.hobbies];
        const index = array.indexOf(e);
        if (index !== -1) {
          array.splice(index, 1);
          this.setState({ hobbies: array }, () => 
         updateHobbies(this.state.hobbies));
        }
      };

      render() {
        return (
          <div>
            <label className='employee-label'>HOBBIES: </label>
            <span>
              <input type='text' value={this.state.userInput} onChange= 
           {this.handleChange} />
              <button className='update-details-button' onClick= 
        {this.handleButtonClick}>
                Add
              </button>

              {this.state.hobbies.map(hobbies => {
                return (
                  <li className='employee-tag-list' key={hobbies}>
                    {hobbies}
                    <span className='delete-icons' onClick={() => 
         this.handleDelete(hobbies)}>
                      <MdDelete />
                    </span>
                  </li>
                );
              })}
            </span>
          </div>
        );
      }
    }
   EditProfile.propTypes = {
  employeeHobbies: PropTypes.array
};

export default EditProfile;

EditProfile.test.js

let component;
  const chance = new Chance();
  let mockHandleChange = jest.fn();
  let mockHandleButtonClick = jest.fn();
  let mockHandleDelete = jest.fn();
  let mockUpdateHobbies;
  let mockHobbies = [chance.string(), chance.string(), chance.string()];

  function requiredProps(overrides = {}) {
    return {
      handleChange: mockHandleChange,
      handleButtonClick: mockHandleButtonClick,
      handleDelete: mockHandleDelete,
      ...overrides
    };
  }

  function renderComponent(props = requiredProps()) {
    return shallow(<Hobbies {...props} />);
  }

  beforeEach(() => {
    component = renderComponent();
  });

  it('should exist', () => {
    console.log(component.debug());
    expect(component).toHaveLength(1);
  });

我希望测试通过,但我收到错误,TypeError: Cannot read property 'map' of undefined

【问题讨论】:

  • 请添加EditProfile.js 的其余部分。我怀疑这是因为您没有正确初始化状态属性(在这种情况下,state.hobbies 没有设置为空数组)。
  • 我刚刚更新了代码
  • 将默认的空数组设置为emloyeeHobbiesEditProfile.defaultProps = { employeeHobbies: [] };
  • state = { 爱好:this.props.employeeHobbies, userInput: '', employeeHobbies: [] };这是你要我做的吗?

标签: reactjs unit-testing jestjs


【解决方案1】:

您可以做一些事情,所有这些都旨在解决核心问题:您没有在测试中为 employeeHobbies 属性提供值。

选择以下选项之一:

  1. 正如@Hoyen 建议的那样,添加默认道具来为employeeHobbies 指定一个空数组(如果未提供)。 EditProfile.defaultProps = { employeeHobbies: [] };
  2. 在您的测试文件中的requiredProps() 函数中,为空数组的employeeHobbies 指定一个值以及handleChangehandleButtonClick 等其他属性。
  3. 初始化state.employeeHobbies 时,将其设置为this.props.employeeHobbies || [],,以便在传递空值或空值(未定义)时具有备用值。

我还建议您将 employeeHobbies 的 proptype 指定为 PropTypes.array.isRequired,以便在未提供数组时获得有用的警告。这将防止滥用该组件,并违反它需要工作的合同。

【讨论】:

  • 我选择了第二个选项,它成功了!谢谢你的帮助!我想知道为什么需要给employeeHobbies设置一个空数组? (所以我不会犯同样的错误。)
  • @PoojaArshanapally 我很高兴它成功了。如果它解决了您的问题,请不要忘记接受并投票赞成这个答案。您需要为employeeHobbies 提供一个有效值(在本例中为空数组),否则在渲染函数中,您将在undefined 上调用.map(),这是您看到的错误。不要忘记在你的 proptypes 上添加 .isRequired 以防止将来出现错误。
  • 扩展我之前的评论,以防不清楚,因为您基于props.employeeHobbies 初始化this.state.employeeHobbies,如果您不为employeeHobbies 属性提供值,它将设置为undefined,因为这就是props.employeeHobbies。这就是为什么在您的测试中,因为您从未为 props.employeeHobbies 定义任何值,您会收到“无法读取未定义的属性 'map'”错误。有意义吗?
猜你喜欢
  • 2021-02-25
  • 2022-01-14
  • 2019-03-02
  • 1970-01-01
  • 1970-01-01
  • 2021-11-17
  • 2022-01-12
  • 2018-02-08
相关资源
最近更新 更多