在前端开发中,测试是一个重要的环节,可以有效地发现和解决代码上的问题。React 应用程序中,我们可以使用 Enzyme 进行组件测试。在本文中,我们将详细介绍如何使用 Enzyme 测试表单。
什么是 Enzyme
Enzyme 是 React 组件的 JavaScript 测试实用程序,它允许您轻松地模拟组件,并对其进行断言。 Enzyme 快速、灵活、强大,对于单元测试和集成测试都非常有用。
Enzyme 提供了三种渲染 React 组件的方式:
- shallow:只渲染包装组件,并不渲染其子组件。这种方式可以测试组件本身,而不关心其子组件。你可以使用
shallow,当你在测试比较复杂的组件时,不用关心子组件的渲染,以免在测试复杂性情况下出现副作用。 - mount:会将组件和其子组件全部渲染出来。这种方式可以测试组件和其子组件之间的交互,和生命周期方法的验证。你可以使用
mount,当你需要测试组件和其所有子组件的交互和行为。 - render:将组件渲染成静态 HTML,并分析生成的 HTML 树。这种方式类似于
mount,但不需要使用 浏览器的API来测试 React 组件。因此,这是最快的测试方法。
测试表单
在 React 中测试表单,需要模拟用户输入场景,我们使用如下的表单组件进行演示:
// www.javascriptcn.com code example
import React from 'react';
class Form extends React.Component {
constructor (props) {
super(props);
this.state = {
username: '',
password: ''
};
this.handleSubmit = this.handleSubmit.bind(this);
this.handleChange = this.handleChange.bind(this);
}
handleChange (event) {
const name = event.target.name;
this.setState({
[name]: event.target.value
});
}
handleSubmit (event) {
event.preventDefault();
if (this.state.username === 'admin' && this.state.password === 'password') {
this.props.onSubmit();
} else {
this.props.onError();
}
}
render () {
return (
<form onSubmit={this.handleSubmit}>
<label>
Username:
<input type="text" name="username" value={this.state.username} onChange={this.handleChange} />
</label>
<label>
Password:
<input type="password" name="password" value={this.state.password} onChange={this.handleChange} />
</label>
<button type="submit">Submit</button>
</form>
);
}
}
export default Form;我们需要测试 Form 组件,输入 admin 和 password 将启动正确的行动,否则将调用失败。
我们可以创建一个测试套件,同时使用 shallow 和 mount 函数分别测试表单的输入和提交:
// www.javascriptcn.com code example
import React from 'react';
import { shallow, mount } from 'enzyme';
import Form from './Form';
describe('Form component', () => {
let component;
let props;
beforeEach(() => {
props = {
onSubmit: jest.fn(),
onError: jest.fn()
};
component = shallow(<Form {...props} />);
});
describe('Test input fields', () => {
it('Should update the username value', () => {
expect(component.find('input[name="username"]').props().value).toEqual('');
component.find('input[name="username"]').simulate('change', { target: { name: 'username', value: 'admin' } });
expect(component.find('input[name="username"]').props().value).toEqual('admin');
});
it('Should update the password value', () => {
expect(component.find('input[name="password"]').props().value).toEqual('');
component.find('input[name="password"]').simulate('change', { target: { name: 'password', value: 'password' } });
expect(component.find('input[name="password"]').props().value).toEqual('password');
});
});
describe('Test form submit', () => {
it('Should submit the form with correct values', () => {
component.find('input[name="username"]').simulate('change', { target: { name: 'username', value: 'admin' } });
component.find('input[name="password"]').simulate('change', { target: { name: 'password', value: 'password' } });
component.find('form').simulate('submit', { preventDefault () {} });
expect(props.onSubmit).toHaveBeenCalled();
});
it('Should show an error message with incorrect values', () => {
component.find('input[name="username"]').simulate('change', { target: { name: 'username', value: 'incorrect' } });
component.find('input[name="password"]').simulate('change', { target: { name: 'password', value: 'incorrect' } });
component.find('form').simulate('submit', { preventDefault () {} });
expect(props.onError).toHaveBeenCalled();
});
});
});首先,我们在 beforeEach 函数中实例化组件,并定义所需的 Props。在测试用例中,我们用 describe 函数分别测试输入和提交阶段。在输入部分,我们测试了输入值的设置和更新;在提交部分,我们测试了正确和错误的用户输入。
Source: FunTeaLearn,Please indicate the source for reprints https://funteas.com/post/67cea34be46428fe9e91ee72