如何使用Jest和Enzyme在React中测试OnSubmit

时间:2019-09-24 18:02:24

标签: reactjs jestjs enzyme

我有以下用于onSubmit函数的代码

handleSubmit(event) {
    event.preventDefault();

    this.setState({ isDone: true });

    const nameMatch= () => {
      return !(this.state.firstName.match("^Cel.*") && this.state.firstName.endsWith("on"))
    }
    if (nameMatch()) {
      alert("Please enter a valid name");
      return;
    }

    if (!this.state.lastName.endsWith("on")) {
      alert("check lastname too");
      return;
    }
    this.getFullName();

}

要运行上面的测试,我要做:

it('check submit', () => {
    wrapper.handleSubmit({preventDefault: () => {}});
    console.log(wrapper.handleSubmit());
});

在这里,我需要名字和姓氏的状态。在测试用例中我该怎么做?如何将它们作为参数传递给测试?

1 个答案:

答案 0 :(得分:1)

这是解决方案,您可以使用.simulate(event[, ...args])的{​​{1}}方法来触发反应域SyntheticEvent。文档:https://airbnb.io/enzyme/docs/api/ShallowWrapper/simulate.html

例如:

enzyme

index.tsx

import React, { Component } from 'react'; export interface ISomeComponentState { firstName: string; lastName: string; isDone: boolean; [key: string]: any; } export class SomeComponent extends Component<any, ISomeComponentState> { constructor(props) { super(props); this.state = { firstName: '', lastName: '', isDone: false }; this.handleSubmit = this.handleSubmit.bind(this); this.handleInputChange = this.handleInputChange.bind(this); } public render() { return ( <div> <form onSubmit={this.handleSubmit}> <label> firstName: <input type="text" name="firstName" placeholder="enter your first name" value={this.state.firstName} onChange={this.handleInputChange} /> </label> <label> lastName: <input type="text" name="lastName" placeholder="enter your last name" value={this.state.lastName} onChange={this.handleInputChange} /> </label> <div> <input type="submit" value="Submit" /> </div> </form> </div> ); } private handleInputChange(event: React.ChangeEvent<HTMLInputElement>) { const target = event.target; const name = target.name; const value = target.value; this.setState({ [name]: value }); } private handleSubmit(event: React.FormEvent<HTMLFormElement>) { event.preventDefault(); this.setState({ isDone: true }); const nameMatch = () => { return !(this.state.firstName.match('^Cel.*') && this.state.firstName.endsWith('on')); }; if (nameMatch()) { alert('Please enter a valid name'); return; } if (!this.state.lastName.endsWith('on')) { alert('check lastname too'); return; } this.getFullName(); } private getFullName() { const { firstName, lastName } = this.state; return firstName + ' ' + lastName; } }

index.spec.tsx

带有覆盖率报告的单元测试:

import React from 'react';
import { shallow, ShallowWrapper } from 'enzyme';
import { SomeComponent, ISomeComponentState } from './';

describe('SomeComponent', () => {
  let wrapper: ShallowWrapper;
  let getFullNameSpy;
  let alertSpy;
  beforeEach(() => {
    alertSpy = jest.spyOn(window, 'alert');
    getFullNameSpy = jest.spyOn(SomeComponent.prototype as any, 'getFullName');
    wrapper = shallow(<SomeComponent></SomeComponent>);
  });
  afterEach(() => {
    jest.resetAllMocks();
  });

  it('check submit', () => {
    expect(wrapper.find('form')).toHaveLength(1);
    const formEventMocked = { preventDefault: jest.fn() };
    const state: ISomeComponentState = {
      firstName: 'Cel.du.on',
      lastName: 'lin.on',
      isDone: false
    };
    wrapper.setState(state);
    expect(wrapper).toMatchSnapshot();
    wrapper.find('form').simulate('submit', formEventMocked);
    expect(getFullNameSpy).toBeCalledTimes(1);
    expect(formEventMocked.preventDefault).toBeCalledTimes(1);
    expect(wrapper.state('isDone')).toBeTruthy();
  });

  it('should alert when first name is invalid', () => {
    expect(wrapper.find('form')).toHaveLength(1);
    const formEventMocked = { preventDefault: jest.fn() };
    const state: ISomeComponentState = {
      firstName: 'du',
      lastName: 'lin.on',
      isDone: false
    };
    wrapper.setState(state);
    expect(wrapper).toMatchSnapshot();
    wrapper.find('form').simulate('submit', formEventMocked);
    expect(alertSpy).toBeCalledWith('Please enter a valid name');
    expect(formEventMocked.preventDefault).toBeCalledTimes(1);
    expect(wrapper.state('isDone')).toBeTruthy();
  });

  it('should alert when last name is invalid', () => {
    expect(wrapper.find('form')).toHaveLength(1);
    const formEventMocked = { preventDefault: jest.fn() };
    const state: ISomeComponentState = {
      firstName: 'Cel.du.on',
      lastName: 'lin',
      isDone: false
    };
    wrapper.setState(state);
    expect(wrapper).toMatchSnapshot();
    wrapper.find('form').simulate('submit', formEventMocked);
    expect(alertSpy).toBeCalledWith('check lastname too');
    expect(formEventMocked.preventDefault).toBeCalledTimes(1);
    expect(wrapper.state('isDone')).toBeTruthy();
  });
});

以下是完整的演示:https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/58085900