开玩笑回应onSubmit不覆盖方法

时间:2018-10-23 08:45:44

标签: javascript reactjs jestjs

我有一个页面,其中包含一个组件,可在发生点击事件时从GET端点搜索请求数据:

AppView.jsx

/**
 * Request and set a list of test values
 * @param {Object} params The response of the search component
*/
fetchData = (params) => {
  const { search } = params;

  this.props.api.test(search)
    .then((response) => {
      objectOrder(response, 'dueDate');
      this.setState({ test: response });
    }).catch(() => {
      this.setState({ test: [] });
    });
}

render() {
  return (
    <SearchComponent fetchData={this.fetchData} />
  );
}

SearchForm / index.jsx

class SearchForm extends Component {
  static propTypes = {
    fetchData: PropTypes.func.isRequired,
  }

  constructor(props) {
    super(props);
    this.state = {
      search: '',
    };
  }

  /**
   * Sets the state of the search name
   * @param {Object} event
   */
  handleChange = (event) => {
    const { name, value } = event.target;
    this.setState({ [name]: value });
  }

  /**
   * Propagate the submit event
   * @param {Object} event
   */
  handleSubmit = (event) => {
    event.preventDefault();
    this.props.fetchData(this.state);
  }

  render() {
    return (
      <FormContainer onSubmit={this.handleSubmit}>
        <Input value={this.state.search} name='search' placeholder='Search for...' onChange={this.handleChange} />
        <Button variant='contained' color='primary'>Buscar</Button>
      </FormContainer>
    );
  }
}

当我对Submit方法进行SearchForm测试时,即使我的所有测试都成功通过,我的覆盖范围也告诉我handleSubmithandleChange方法根本没有被测试:< / p>

enter image description here

我的测试尝试通过以下方式测试这些方法:

describe('<SearchForm />', () => {
  const text = 'This is a text for a test';
  const state = { search: text };
  let props;
  let wrapper;

  beforeEach(() => {
    props = {
      handleSubmit: jest.fn(() => true),
      fetchData: jest.fn(() => (state)),
    };

    wrapper = mount(<SearchForm {...props} />);
  });

  test('It should call handlesubmit method when submitting the form', (done) => {
    wrapper.find(Button).simulate('click', { preventDefault() {} });
    expect(wrapper.props().handleSubmit()).toEqual(true);
    done();
  });

  test('It should call handleChange method', (done) => {
    const input = wrapper.find(Input);

    input.props().value = text;
    input.simulate('change', { target: { value: text } });
    expect(input.get(0).props.value).toEqual(text);
    done();
  });
});

涵盖所有这些方法的帮助吗?

感谢您的咨询

1 个答案:

答案 0 :(得分:0)

您可以模拟submit表单事件。

SearchForm.tsx

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { FormContainer } from './FormContainer';
import { Input } from './Input';
import { Button } from './Button';

interface ISearchFormDispatchProps {
  fetchData(params: ISearchFormState): any;
}

type Props = ISearchFormDispatchProps;

interface ISearchFormState {
  search: string;
  [key: string]: string;
}

export class SearchForm extends Component<Props, ISearchFormState> {
  public static propTypes = {
    fetchData: PropTypes.func.isRequired
  };

  constructor(props) {
    super(props);
    this.state = {
      search: ''
    };
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  /**
   * Sets the state of the search name
   * @param {Object} event
   */
  public handleChange = event => {
    const { name, value } = event.target;
    this.setState({ [name]: value });
  }

  /**
   * Propagate the submit event
   * @param {Object} event
   */
  public handleSubmit = event => {
    event.preventDefault();
    this.props.fetchData(this.state);
  }

  public render() {
    return (
      <FormContainer onSubmit={this.handleSubmit}>
        <Input value={this.state.search} name="search" placeholder="Search for..." onChange={this.handleChange} />
        <Button variant="contained" color="primary">
          Buscar
        </Button>
      </FormContainer>
    );
  }
}

FormContainer.tsx

import React, { Component } from 'react';

interface IFormContainerOwnProps {
  children: React.ReactElement[];
  onSubmit(e: React.FormEvent<HTMLFormElement>): any;
}

export class FormContainer extends Component<IFormContainerOwnProps> {
  constructor(props: IFormContainerOwnProps) {
    super(props);
  }
  public render() {
    return (
      <div>
        <form onSubmit={this.props.onSubmit}>{this.props.children}</form>
      </div>
    );
  }
}

Button.tsx

import React from 'react';

export const Button = props => {
  return <button {...props}>{props.children}</button>;
};

Input.tsx

import React from 'react';

export const Input = ({ onChange, placeholder, name, value }) => {
  return <input placeholder={placeholder} name={name} value={value} onChange={onChange}></input>;
};

SearchForm.spec.ts单元测试:

import React from 'react';
import { SearchForm } from './SearchForm';
import { mount } from 'enzyme';
import { Input } from './Input';

describe('SearchForm', () => {
  const text = 'This is a text for a test';
  const state = { search: text };
  let props;
  let wrapper;

  beforeEach(() => {
    props = {
      fetchData: jest.fn(() => state)
    };

    wrapper = mount(<SearchForm {...props} />);
  });

  test('It should call handlesubmit method when submitting the form', done => {
    const mockedFormEvent = {
      preventDefault: jest.fn()
    };
    wrapper.find('form').simulate('submit', mockedFormEvent);
    expect(wrapper.props().fetchData).toBeCalledWith(wrapper.state());
    expect(mockedFormEvent.preventDefault).toBeCalledTimes(1);
    done();
  });

  test('It should call handleChange method', done => {
    const input = wrapper.find(Input);

    input.props().value = text;
    input.simulate('change', { target: { value: text } });
    expect(input.get(0).props.value).toEqual(text);
    done();
  });
});

覆盖率100%的单元测试结果:

 PASS  src/stackoverflow/52944804/SearchForm.spec.tsx
  SearchForm
    ✓ It should call handlesubmit method when submitting the form (53ms)
    ✓ It should call handleChange method (16ms)

-------------------|----------|----------|----------|----------|-------------------|
File               |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
-------------------|----------|----------|----------|----------|-------------------|
All files          |      100 |      100 |      100 |      100 |                   |
 Button.tsx        |      100 |      100 |      100 |      100 |                   |
 FormContainer.tsx |      100 |      100 |      100 |      100 |                   |
 Input.tsx         |      100 |      100 |      100 |      100 |                   |
 SearchForm.tsx    |      100 |      100 |      100 |      100 |                   |
-------------------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        4.953s, estimated 5s

SearchForm.tsx的覆盖率报告:

enter image description here

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