Since react-drip-form
is a HoC based API, it can easily be tested by mocking Props.
Here is an example of testing using enzyme + jest.
Of course, it is also possible to use other testing frameworks.
As a first step let’s export the components before wrapping in Forms
, Field
, FieldGroup
, HoC respectively.
Input.js
import { dripFormField } from 'react-drip-form';
// Use `named exports`, for pure component.
export const Input = ({ input, meta, ...rest }) => {
/* field component .... */
};
export default dripFormField()(Input);
Input.spec.js
import { Input } from './Input';
describe('<Input />', () => {
test('Should be render control', () => {
/* your testing ... */
});
});
It is very easy to test using react-drip-form-test-utils to pass mocks to Context and Props.
$ npm install --save-dev react-drip-form-test-utils
We will test it from the Form
component which is essential for building the form.
The test target is the next simple component.
Form.js
import React from 'react';
import { dripForm } from 'react-drip-form';
import Input from './Input';
export const Form = ({ handlers }) => (
<form onSubmit={handlers.onSubmit}>
<div>
<Input
type="text"
name="username"
label="Username"
/>
</div>
<button onClick={handlers.onSubmit}>Submit</button>
</form>
);
export default dripForm({
validations: {
username: {
required: true,
},
},
})(Form);
For this Form
component, we will perform the following tests.
Let’s test whether the form will be rendered as expected.
Use mockContext
andmockFormProps
provided by react-drip-form-test-utils
to mock Context and Props respectively.
Form.spec.js
import React from 'react';
import { shallow } from 'enzyme';
import { mockContext, mockFormProps } from 'react-drip-form-test-utils';
import { Form } from '../Form';
import Input from '../Input';
describe('<Form />', () => {
// Rendering tests
test('Should be render forms', () => {
const context = mockContext();
const props = mockFormProps();
const wrapper = shallow(<Form {...props} />, { context });
expect(wrapper.contains(
<Input
type="text"
name="username"
label="Username"
/>
)).toBe(true);
});
});
You can do more detailed testing using the API provided by enzyme.
See enzyme for details.
The point here is that passing mocks to Context and Props makes it possible to test components that are not wrapped with dripForm()
.
Next, let’s test whether handlers.onSubmit()
is called as expected.
Form.spec.js
describe('<Form />', () => {
// ...
// Handling tests
test('Should be handle submit', () => {
const onSubmit = jest.fn();
const props = mockFormProps({
handlers: {
onSubmit,
},
});
const wrapper = shallow(
<Form {...props} />
);
expect(onSubmit.mock.calls.length).toBe(0);
wrapper.find('button').simulate('click');
expect(onSubmit.mock.calls.length).toBe(1);
});
});
Passing a mock function to handlers.onSubmit()
makes it easy to write tests.
The concept of Field components is similar to Forms components.
The test target is the following components.
Input.js
import React from 'react';
import { dripFormField } from 'react-drip-form';
export const Input = ({
input,
meta,
...props
}) => (
<div>
<input
{...props}
{...input}
/>
{meta.error && meta.dirty && meta.touched &&
<div className="error">{meta.error}</div>
}
</div>
);
export default dripFormField()(Input);
Unlike Forms, mock the field Props using mockFieldProps
.
Input.spec.js
import React from 'react';
import { shallow } from 'enzyme';
import { mockFieldProps } from 'react-drip-form-test-utils';
import { Input } from '../Input';
describe('<Input />', () => {
// Rendering tests
test('Should be render field', () => {
const props = mockFieldProps();
const wrapper = shallow(<Input {...props} />);
const {
input,
meta,
...rest
} = props;
expect(wrapper.equals(
<div>
<input
{...input}
{...rest}
/>
</div>
)).toBe(true);
});
});
Testing with Snapshot makes it easier to test.
Input.spec.js
describe('<Input />', () => {
// ...
test('Should be render field', () => {
const props = mockFieldProps();
const wrapper = shallow(<Input {...props} />);
expect(wrapper).toMatchSnapshot();
});
});
Next test whether error text is displayed.
describe('<Input />', () => {
// ...
test('Should be render error text', () => {
const props = mockFieldProps({
meta: {
error: 'Error Text',
dirty: true,
touched: true,
},
});
const wrapper = shallow(<Input {...props} />);
expect(wrapper.contains(
<div className="error">Error Text</div>
)).toBe(true);
});
});
Test the following FieldGroup components.
import React from 'react';
import { dripFormGroup } from 'react-drip-form';
export const FieldGroup = ({
meta,
children,
...props
}) => (
<div {...props}>
{children}
{meta.error && meta.touched && meta.dirty &&
<div className="error">{meta.error}</div>
}
</div>
);
export default dripFormGroup()(FieldGroup);
FieldGroup The easiest to test is ever. Except using mockGroupProps
for Props’ mock, you can test it just like a Field component.
import React from 'react';
import { shallow } from 'enzyme';
import { mockGroupProps } from 'react-drip-form-test-utils';
import { FieldGroup } from '../FieldGroup';
describe('<FieldGroup />', () => {
test('Should be render children', () => {
const props = mockGroupProps();
const element = <div className="child">Group Child</div>;
const wrapper = shallow(
<FieldGroup {...props}>
{element}
</FieldGroup>
);
expect(wrapper.contains(element)).toBe(true);
});
test('Should be render error text', () => {
const props = mockGroupProps({
meta: {
error: 'Error Text',
dirty: true,
touched: true,
},
});
const wrapper = shallow(<FieldGroup {...props} />);
expect(wrapper.contains(
<div className="error">Error Text</div>
)).toBe(true);
});
});
This is how we introduced a test method.
Have a good testing life!