Jest+Enzyme前端单元测试react项目实战

1,906 阅读1分钟

react项目使用create-react-app的脚手架搭建,使用react hooks,antd组件库。

login组件

import React from 'react';
import { Form, Input, Button, Icon } from 'antd';

function Login({ form, history }){
  handleSubmit = e => {
    e.preventDefault();
    form.validateFields((err, values) => {
      if (!err) {
        api.login(values).then( res => {
            const { data, code } = res;
            if( code === 200 ){
                history.push('/');
            }
        })
      }
    });
  };

  render() {
    const { getFieldDecorator } = form;
    return (
      <Form>
        <Form.Item>
          {getFieldDecorator('username', {
            rules: [{ required: true, message: '请输入用户名!' }],
          })(
            <Input
              prefix={<Icon type="user" style={{ color: 'rgba(0,0,0,.25)' }} />}
            />,
          )}
        </Form.Item>
        <Form.Item>
          {getFieldDecorator('password', {
            rules: [{ required: true, message: '请输入密码!' }],
          })(
            <Input
              prefix={<Icon type="lock" style={{ color: 'rgba(0,0,0,.25)' }} />}
              type="password"
            />,
          )}
        </Form.Item>
        <Form.Item>
          <Button type="primary" onClick={handleSubmit}>
            登录
          </Button>
        </Form.Item>
      </Form>
    );
  }
}
export default Form.create()(Login);

测试准备

import React from 'react';
import Login from './login';
import renderer from 'react-test-renderer';
import Enzyme, {mount} from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';

Enzyme.configure({ adapter: new Adapter() });

function setup(){
    const props = {
        history: {
            push: jest.fn(),
        },
    };
    const wrapper = mount(<Login {...props} />);
    return {
        wrapper,
        props,
    }
}

快照测试

test('快照测试', () => {
    const { props } = setup();
    const tree = renderer.create(<Login {...props} />);
    expect(tree.toJSON()).toMatchSnapshot();
});

测试组件是否正确渲染

test('渲染登录按钮', ()=>{
    const { wrapper } = setup();
    expect(wrapper.find('button').text()).toBe('登录');
})
test('渲染2个输入框', ()=>{
    const { mount } = setup();
    expect(wrapper.find('input').length).toBe(2);
}

测试不输入信息,点击登录按钮,开启form表单验证

test('', ()=>{
    const { mount } = setup();
    wrapper.find('button').simulate('click');
    expect(wrapper.find('.antd-form-explain').length).toBe(2);
    expect(wrapper.find('.antd-form-explain').at(0).text()).toBe('请输入用户名!');
    expect(wrapper.find('.antd-form-explain').at(1).text()).toBe('请输入密码!');
})

测试输入信息,点击登录按钮,登录接口返回200,跳转页面

需要mock api文件,在api文件同一目录位置,新建文件夹__mocks__,里面新建同名api文件

const login = () => {
    return Promise.resolved({
        data: {
            code: 200,
            message: '登录成功',
        }
    })
}
jest.mock('../api');
test('', (done)=>{
    const { mount, props } = setup();
    wrapper.find('input').at(0).simulate('change', {
        target: {
            value: 'admin',
        }
    });
    wrapper.find('input').at(1).simulate('change',{
        target: {
            value: '123456',
        }
    });
    wrapper.find('button').simulate('click');
    process.nextick(()=>{
        expect(props.history.push).toHaveBeenCalled();
        done();
    })
}