javascript - 如何测试更改组件状态的函数?

标签 javascript reactjs ecmascript-6 jestjs enzyme

我有这个组件:

// imports

class FiltersModal extends React.Component {
  state = {
    status: '',
    carrier: '',
  };

  applyFilters = () => {
    const { applyFilters } = this.props;
    const {
      status,
      carrier,
    } = this.state;

    applyFilters({
      status,
      carrier,
    });
  };

  handleChange = field => ev => {
    this.setState({ [field]: ev.target.value });
  };

  render() {
    const { t, isFiltersModalOpened, toggleFiltersModal } = this.props;
    const { shippedDate } = this.state;

    return (
      <Modal
        open={isFiltersModalOpened}
        onRequestClose={toggleFiltersModal}
        onRequestSubmit={this.applyFilters}
      >
        <Form>

          <StatusesSelect handleStatus={this.handleChange('status')} />
          <GetAllCouriers handleCouriers={this.handleChange('carrier')} />

        </Form>
      </Modal>
    );
  }
}

FiltersModal.propTypes = {
  t: PropTypes.func.isRequired,
  isFiltersModalOpened: PropTypes.bool.isRequired,
  toggleFiltersModal: PropTypes.func.isRequired,
  applyFilters: PropTypes.func.isRequired,
};

export default translate()(FiltersModal);

这个测试:

import React from 'react';
import { shallow } from 'enzyme';
import FiltersModal from '../../FiltersModal';

jest.mock('react-i18next', () => ({
  // this mock makes sure any components using the translate HoC receive the t function as a prop
  translate: () => Component => {
    Component.defaultProps = { ...Component.defaultProps, t: key => key }; // eslint-disable-line
    return Component;
  },
}));

describe('FiltersModal component test', () => {
  let props;

  beforeEach(() => {
    props = {
      t: k => k,
      isFiltersModalOpened: false,
      toggleFiltersModal: jest.fn(() => k => k),
      removeFilter: jest.fn(() => k => k),
      applyFilters: jest.fn(() => k => k),
      softlayerAccountId: '232279',
      filters: {
        carrier: 'UPS',
        shipmentId: '1234',
        shipmentType: '',
        shippedDate: '',
        shippedFrom: '',
        shippedTo: '',
        status: '',
      },
    };
  });

  it('should render without errors', () => {
    const wrapper = shallow(<FiltersModal {...props} />);

    expect(wrapper.find('Modal')).toHaveLength(1);
    expect(wrapper.find('Form')).toHaveLength(1);
  });

  it('should change state', () => {
    const wrapper = shallow(<FiltersModal {...props} />);

    wrapper.setState({ carrier: 'UPS' });

    wrapper.instance().applyFilters();
    wrapper.instance().handleChange('status');

    expect(props.applyFilters).toHaveBeenCalledTimes(1);
    expect(wrapper.instance().handleChange).toHaveBeenCalledTimes(1);
  });
});

我需要调用函数handleChange,但我收到此错误:

 FAIL  src/client/pages/Shipments/__tests__/components/FiltersModal-test.js
  FiltersModal component test
    ✓ should render without errors (15ms)
    ✕ should change state (12ms)

  ● FiltersModal component test › should change state

    expect(jest.fn())[.not].toHaveBeenCalledTimes()

    jest.fn() value must be a mock function or spy.
    Received:
      function: [Function anonymous]

      51 | 
      52 |     expect(props.applyFilters).toHaveBeenCalledTimes(1);
    > 53 |     expect(wrapper.instance().handleChange).toHaveBeenCalledTimes(1);
         |                                             ^
      54 |   });
      55 | });
      56 | 

我错过了什么?

最佳答案

我相信你不需要这个。与在实际项目中一样,您通常不会从外部与组件的方法进行通信(调用实例方法的 ref 是一个异常(exception))。相反,您依赖于 render() 返回的内容。

因此,我建议您确保更改的值通过 applyFilters 传到外部:

it('should change state', () => {
  const applyFiltersMock = jest.fn();
  const wrapper = shallow(<FiltersModal {...props} applyFilters={applyFiltersMock} />);
  wrapper.find(StatusesSelect).props().handleStatus({ target: {value: '2'} });
  wrapper.find(GetAllCouriers ).props().handleCouriers({ target: {value: '3'} });

  wrapper.find(Modal).props().onRequestSubmit();
  expect(applyFiltersMock).toHaveBeenCalledTimes(1);
  expect(applyFiltersMock).toHaveBeenCalledWith({status: '2', carrier: '3'});
});

关于javascript - 如何测试更改组件状态的函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54332495/

相关文章:

javascript - Wordpress Bones 主题 CSS 和 JS 版本控制

javascript - 带有 Javascript 的 HTML5 视频播放/停止按钮

javascript - 页面未渲染;在react-router-dom中使用 protected 路由将 Prop 传递给子级时

javascript - 我可以通过 Prop 传递要使用的对象名称吗?

javascript - 我如何检测是否安装了 Flash,如果没有,显示一个隐藏的 div 来通知用户?

javascript - 变量 = getElementById ("something").value 丢失一半数据?

reactjs - React props 的恰好一个/有区别的联合

javascript - React : in mobile browsers button onClick hadler fires multiple times. 桌面版没问题

javascript - 避免在 javascript 中循环多次返回 - async/await 以解决回调金字塔或回调 hell ,

javascript - ES6 对于每个/ map 学生成绩