How to test components wrapped in an antd Form?
I've been struggling with this for months, now. Although there's a lot of speculation on the correct way to test antd wrapped components, none of the suggestions worked for this particular component.
So, I have a component which is a modal with an antd form. In this form, I have a few fields: an input, a select and a tree select, nothing too fancy.
It's basically this:
class FormModal extends React.Component {
static propTypes = {
data: propTypes.object,
form: propTypes.object,
scopes: propTypes.array.isRequired,
clients: propTypes.array.isRequired,
treeData: propTypes.array.isRequired,
isEditing: propTypes.bool.isRequired,
isSaving: propTypes.bool.isRequired,
onCancel: propTypes.func.isRequired,
onSave: propTypes.func.isRequired,
onFilterTreeData: propTypes.func.isRequired,
visible: propTypes.bool.isRequired
}
static defaultProps = {
data: null,
form: {}
}
state = {
selectedScopes: ,
newScopes: ,
inputVisible: false,
inputValue: ''
};
componentDidMount() {
// do stuff
}
handleSave = () => {
// do stuff
}
handleSelectedScopesChange = (event) => {
// do stuff
}
updateTreeSelect = () => {
const { form } = this.props;
const { selectedScopes } = this.state;
form.setFieldsValue({
allowedScopes: selectedScopes
});
}
handleRemoveTag = (removedTag) => {
const selectedScopes = this.state.selectedScopes.filter(scope => scope !== removedTag);
const newScopes = this.state.newScopes.filter(scope => scope !== removedTag);
this.setState({ selectedScopes, newScopes }, this.updateTreeSelect);
}
showInput = () => {
this.setState({ inputVisible: true }, () => this.input.focus());
}
handleInputChange = (e) => {
const inputValue = e.target.value;
this.setState({ inputValue });
}
handleInputConfirm = () => {
const { newScopes, inputValue } = this.state;
let tags = newScopes;
if (inputValue && tags.indexOf(inputValue) === -1) {
tags = [inputValue, ...tags];
}
this.setState({
newScopes: tags,
inputVisible: false,
inputValue: '',
});
}
saveInputRef = input => this.input = input
renderTags = (scopeArrays) => {
const tags = scopeArrays.map(scopeArray =>
scopeArray.map((permition) => {
let scopeType = null;
if (permition.includes('read') || permition.includes('get')) scopeType = 'blue';
if (permition.includes('create') || permition.includes('write') || permition.includes('send')) scopeType = 'green';
if (permition.includes('update')) scopeType = 'gold';
if (permition.includes('delete')) scopeType = 'red';
return (
<Tag
key={permition}
color={scopeType || 'purple'}
style={{ margin: '2px 4px 2px 0' }}
closable
afterClose={() => this.handleRemoveTag(permition)}
>
{permition}
</Tag>
);
})
);
return .concat(...tags);
}
render() {
const {
selectedScopes,
newScopes,
inputValue,
inputVisible
} = this.state;
const {
form,
treeData,
clients,
isEditing,
isSaving,
onCancel,
onFilterTreeData,
visible
} = this.props;
const {
getFieldDecorator,
getFieldsError,
} = form;
const selectedScopesTags = this.renderTags([newScopes, selectedScopes]);
const clientOptions = clients.map(client => (<Option key={client._id}>{client.name}</Option>));
return (
<Modal
className="user-modal"
title={isEditing ? 'Editing Group' : 'Creating Group'}
visible={visible}
onCancel={onCancel}
footer={[
<Button key="cancel" onClick={onCancel}>Cancel</Button>,
<Button
key="save"
type="primary"
loading={isSaving}
onClick={this.handleSave}
disabled={formRules.hasErrors(getFieldsError())}
>
Save
</Button>
]}
>
<Form layout="vertical" onSubmit={this.handleSave}>
<Row gutter={24}>
<Col span={12}>
<FormItem label="Name">
{getFieldDecorator(
'name',
{ rules: [formRules.required, { max: 20, message: 'Group name can't excede 20 characters' }] }
)(
<Input />
)}
</FormItem>
</Col>
<Col span={12}>
<FormItem label="Client">
{getFieldDecorator(
'client', { rules: [formRules.required] }
)(
<Select placeholder="Please select client">
{clientOptions}
</Select>
)}
</FormItem>
</Col>
<Col span={24}>
<FormItem label="Scopes">
{getFieldDecorator(
'allowedScopes'
)(
<TreeSelect
treeData={treeData}
filterTreeNode={onFilterTreeData}
onChange={this.handleSelectedScopesChange}
treeCheckable
dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
showCheckedStrategy="SHOW_PARENT"
searchPlaceholder="Filter by scopes"
className="groups__filter groups__filter--fill"
/>
)}
</FormItem>
</Col>
<Col span={24}>
<Card
title="Selected Scopes"
style={{ width: '100%' }}
>
<div>
{inputVisible && (
<Input
ref={this.saveInputRef}
type="text"
size="small"
style={{ width: 350 }}
value={inputValue}
onChange={this.handleInputChange}
onBlur={this.handleInputConfirm}
onPressEnter={this.handleInputConfirm}
/>
)}
{!inputVisible && (
<Tag
onClick={this.showInput}
style={{ background: '#fff', borderStyle: 'dashed', margin: '5px 0' }}
>
<Icon type="plus" /> New Scope
</Tag>
)}
</div>
{ selectedScopesTags.length > 0 ? (
selectedScopesTags
) : <p>No scopes selected yet.</p> }
</Card>
</Col>
</Row>
</Form>
</Modal>
);
}
}
export default Form.create()(FormModal);
I know that this component is urging for a refactoring, but that's not my job right now. I need to UI test this and validate if everything is working properly.
I'm trying to test if the form fields are rendering properly. I'm using Jest and Enzyme and so far I got this:
describe('Groups modal', () => {
let props;
const groupsModal = () =>
mount(
<FormModal.WrappedComponent {...props} />
)
beforeEach(() => {
props = {
data: null,
scopes: ,
clients: ,
treeData: ,
isEditing: false,
isSaving: false,
onCancel: jest.fn(),
onSave: jest.fn(),
onFilterTreeData: jest.fn(),
visible: true,
form: {
getFieldsError: jest.fn(() => { return {} }),
getFieldDecorator: () => (component) => component
}
};
});
it('should render properly', () => {
const wrapperDivChilds = groupsModal().find('.user-modal').children();
expect(wrapperDivChilds.length).toBeGreaterThanOrEqual(1);
});
describe('form fields', () => {
it('should render name input', () => {
const nameInput = groupsModal().find(Input);
expect(nameInput.length).toBe(1);
});
it('should render clients select', () => {
const clientsSelect = groupsModal().find(Select);
expect(clientsSelect.length).toBe(1);
});
it('should render scopes tree select', () => {
const scopesTreeSelect = groupsModal().find(TreeSelect);
expect(scopesTreeSelect.length).toBe(1);
});
});
});
All of my tests that validate if the inputs were rendered are failing.
As you can see, I tried mocking the form decorator functions, but still no success...
So, my question is: how should I test this component?
reactjs testing jestjs antd ui-testing
add a comment |
I've been struggling with this for months, now. Although there's a lot of speculation on the correct way to test antd wrapped components, none of the suggestions worked for this particular component.
So, I have a component which is a modal with an antd form. In this form, I have a few fields: an input, a select and a tree select, nothing too fancy.
It's basically this:
class FormModal extends React.Component {
static propTypes = {
data: propTypes.object,
form: propTypes.object,
scopes: propTypes.array.isRequired,
clients: propTypes.array.isRequired,
treeData: propTypes.array.isRequired,
isEditing: propTypes.bool.isRequired,
isSaving: propTypes.bool.isRequired,
onCancel: propTypes.func.isRequired,
onSave: propTypes.func.isRequired,
onFilterTreeData: propTypes.func.isRequired,
visible: propTypes.bool.isRequired
}
static defaultProps = {
data: null,
form: {}
}
state = {
selectedScopes: ,
newScopes: ,
inputVisible: false,
inputValue: ''
};
componentDidMount() {
// do stuff
}
handleSave = () => {
// do stuff
}
handleSelectedScopesChange = (event) => {
// do stuff
}
updateTreeSelect = () => {
const { form } = this.props;
const { selectedScopes } = this.state;
form.setFieldsValue({
allowedScopes: selectedScopes
});
}
handleRemoveTag = (removedTag) => {
const selectedScopes = this.state.selectedScopes.filter(scope => scope !== removedTag);
const newScopes = this.state.newScopes.filter(scope => scope !== removedTag);
this.setState({ selectedScopes, newScopes }, this.updateTreeSelect);
}
showInput = () => {
this.setState({ inputVisible: true }, () => this.input.focus());
}
handleInputChange = (e) => {
const inputValue = e.target.value;
this.setState({ inputValue });
}
handleInputConfirm = () => {
const { newScopes, inputValue } = this.state;
let tags = newScopes;
if (inputValue && tags.indexOf(inputValue) === -1) {
tags = [inputValue, ...tags];
}
this.setState({
newScopes: tags,
inputVisible: false,
inputValue: '',
});
}
saveInputRef = input => this.input = input
renderTags = (scopeArrays) => {
const tags = scopeArrays.map(scopeArray =>
scopeArray.map((permition) => {
let scopeType = null;
if (permition.includes('read') || permition.includes('get')) scopeType = 'blue';
if (permition.includes('create') || permition.includes('write') || permition.includes('send')) scopeType = 'green';
if (permition.includes('update')) scopeType = 'gold';
if (permition.includes('delete')) scopeType = 'red';
return (
<Tag
key={permition}
color={scopeType || 'purple'}
style={{ margin: '2px 4px 2px 0' }}
closable
afterClose={() => this.handleRemoveTag(permition)}
>
{permition}
</Tag>
);
})
);
return .concat(...tags);
}
render() {
const {
selectedScopes,
newScopes,
inputValue,
inputVisible
} = this.state;
const {
form,
treeData,
clients,
isEditing,
isSaving,
onCancel,
onFilterTreeData,
visible
} = this.props;
const {
getFieldDecorator,
getFieldsError,
} = form;
const selectedScopesTags = this.renderTags([newScopes, selectedScopes]);
const clientOptions = clients.map(client => (<Option key={client._id}>{client.name}</Option>));
return (
<Modal
className="user-modal"
title={isEditing ? 'Editing Group' : 'Creating Group'}
visible={visible}
onCancel={onCancel}
footer={[
<Button key="cancel" onClick={onCancel}>Cancel</Button>,
<Button
key="save"
type="primary"
loading={isSaving}
onClick={this.handleSave}
disabled={formRules.hasErrors(getFieldsError())}
>
Save
</Button>
]}
>
<Form layout="vertical" onSubmit={this.handleSave}>
<Row gutter={24}>
<Col span={12}>
<FormItem label="Name">
{getFieldDecorator(
'name',
{ rules: [formRules.required, { max: 20, message: 'Group name can't excede 20 characters' }] }
)(
<Input />
)}
</FormItem>
</Col>
<Col span={12}>
<FormItem label="Client">
{getFieldDecorator(
'client', { rules: [formRules.required] }
)(
<Select placeholder="Please select client">
{clientOptions}
</Select>
)}
</FormItem>
</Col>
<Col span={24}>
<FormItem label="Scopes">
{getFieldDecorator(
'allowedScopes'
)(
<TreeSelect
treeData={treeData}
filterTreeNode={onFilterTreeData}
onChange={this.handleSelectedScopesChange}
treeCheckable
dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
showCheckedStrategy="SHOW_PARENT"
searchPlaceholder="Filter by scopes"
className="groups__filter groups__filter--fill"
/>
)}
</FormItem>
</Col>
<Col span={24}>
<Card
title="Selected Scopes"
style={{ width: '100%' }}
>
<div>
{inputVisible && (
<Input
ref={this.saveInputRef}
type="text"
size="small"
style={{ width: 350 }}
value={inputValue}
onChange={this.handleInputChange}
onBlur={this.handleInputConfirm}
onPressEnter={this.handleInputConfirm}
/>
)}
{!inputVisible && (
<Tag
onClick={this.showInput}
style={{ background: '#fff', borderStyle: 'dashed', margin: '5px 0' }}
>
<Icon type="plus" /> New Scope
</Tag>
)}
</div>
{ selectedScopesTags.length > 0 ? (
selectedScopesTags
) : <p>No scopes selected yet.</p> }
</Card>
</Col>
</Row>
</Form>
</Modal>
);
}
}
export default Form.create()(FormModal);
I know that this component is urging for a refactoring, but that's not my job right now. I need to UI test this and validate if everything is working properly.
I'm trying to test if the form fields are rendering properly. I'm using Jest and Enzyme and so far I got this:
describe('Groups modal', () => {
let props;
const groupsModal = () =>
mount(
<FormModal.WrappedComponent {...props} />
)
beforeEach(() => {
props = {
data: null,
scopes: ,
clients: ,
treeData: ,
isEditing: false,
isSaving: false,
onCancel: jest.fn(),
onSave: jest.fn(),
onFilterTreeData: jest.fn(),
visible: true,
form: {
getFieldsError: jest.fn(() => { return {} }),
getFieldDecorator: () => (component) => component
}
};
});
it('should render properly', () => {
const wrapperDivChilds = groupsModal().find('.user-modal').children();
expect(wrapperDivChilds.length).toBeGreaterThanOrEqual(1);
});
describe('form fields', () => {
it('should render name input', () => {
const nameInput = groupsModal().find(Input);
expect(nameInput.length).toBe(1);
});
it('should render clients select', () => {
const clientsSelect = groupsModal().find(Select);
expect(clientsSelect.length).toBe(1);
});
it('should render scopes tree select', () => {
const scopesTreeSelect = groupsModal().find(TreeSelect);
expect(scopesTreeSelect.length).toBe(1);
});
});
});
All of my tests that validate if the inputs were rendered are failing.
As you can see, I tried mocking the form decorator functions, but still no success...
So, my question is: how should I test this component?
reactjs testing jestjs antd ui-testing
add a comment |
I've been struggling with this for months, now. Although there's a lot of speculation on the correct way to test antd wrapped components, none of the suggestions worked for this particular component.
So, I have a component which is a modal with an antd form. In this form, I have a few fields: an input, a select and a tree select, nothing too fancy.
It's basically this:
class FormModal extends React.Component {
static propTypes = {
data: propTypes.object,
form: propTypes.object,
scopes: propTypes.array.isRequired,
clients: propTypes.array.isRequired,
treeData: propTypes.array.isRequired,
isEditing: propTypes.bool.isRequired,
isSaving: propTypes.bool.isRequired,
onCancel: propTypes.func.isRequired,
onSave: propTypes.func.isRequired,
onFilterTreeData: propTypes.func.isRequired,
visible: propTypes.bool.isRequired
}
static defaultProps = {
data: null,
form: {}
}
state = {
selectedScopes: ,
newScopes: ,
inputVisible: false,
inputValue: ''
};
componentDidMount() {
// do stuff
}
handleSave = () => {
// do stuff
}
handleSelectedScopesChange = (event) => {
// do stuff
}
updateTreeSelect = () => {
const { form } = this.props;
const { selectedScopes } = this.state;
form.setFieldsValue({
allowedScopes: selectedScopes
});
}
handleRemoveTag = (removedTag) => {
const selectedScopes = this.state.selectedScopes.filter(scope => scope !== removedTag);
const newScopes = this.state.newScopes.filter(scope => scope !== removedTag);
this.setState({ selectedScopes, newScopes }, this.updateTreeSelect);
}
showInput = () => {
this.setState({ inputVisible: true }, () => this.input.focus());
}
handleInputChange = (e) => {
const inputValue = e.target.value;
this.setState({ inputValue });
}
handleInputConfirm = () => {
const { newScopes, inputValue } = this.state;
let tags = newScopes;
if (inputValue && tags.indexOf(inputValue) === -1) {
tags = [inputValue, ...tags];
}
this.setState({
newScopes: tags,
inputVisible: false,
inputValue: '',
});
}
saveInputRef = input => this.input = input
renderTags = (scopeArrays) => {
const tags = scopeArrays.map(scopeArray =>
scopeArray.map((permition) => {
let scopeType = null;
if (permition.includes('read') || permition.includes('get')) scopeType = 'blue';
if (permition.includes('create') || permition.includes('write') || permition.includes('send')) scopeType = 'green';
if (permition.includes('update')) scopeType = 'gold';
if (permition.includes('delete')) scopeType = 'red';
return (
<Tag
key={permition}
color={scopeType || 'purple'}
style={{ margin: '2px 4px 2px 0' }}
closable
afterClose={() => this.handleRemoveTag(permition)}
>
{permition}
</Tag>
);
})
);
return .concat(...tags);
}
render() {
const {
selectedScopes,
newScopes,
inputValue,
inputVisible
} = this.state;
const {
form,
treeData,
clients,
isEditing,
isSaving,
onCancel,
onFilterTreeData,
visible
} = this.props;
const {
getFieldDecorator,
getFieldsError,
} = form;
const selectedScopesTags = this.renderTags([newScopes, selectedScopes]);
const clientOptions = clients.map(client => (<Option key={client._id}>{client.name}</Option>));
return (
<Modal
className="user-modal"
title={isEditing ? 'Editing Group' : 'Creating Group'}
visible={visible}
onCancel={onCancel}
footer={[
<Button key="cancel" onClick={onCancel}>Cancel</Button>,
<Button
key="save"
type="primary"
loading={isSaving}
onClick={this.handleSave}
disabled={formRules.hasErrors(getFieldsError())}
>
Save
</Button>
]}
>
<Form layout="vertical" onSubmit={this.handleSave}>
<Row gutter={24}>
<Col span={12}>
<FormItem label="Name">
{getFieldDecorator(
'name',
{ rules: [formRules.required, { max: 20, message: 'Group name can't excede 20 characters' }] }
)(
<Input />
)}
</FormItem>
</Col>
<Col span={12}>
<FormItem label="Client">
{getFieldDecorator(
'client', { rules: [formRules.required] }
)(
<Select placeholder="Please select client">
{clientOptions}
</Select>
)}
</FormItem>
</Col>
<Col span={24}>
<FormItem label="Scopes">
{getFieldDecorator(
'allowedScopes'
)(
<TreeSelect
treeData={treeData}
filterTreeNode={onFilterTreeData}
onChange={this.handleSelectedScopesChange}
treeCheckable
dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
showCheckedStrategy="SHOW_PARENT"
searchPlaceholder="Filter by scopes"
className="groups__filter groups__filter--fill"
/>
)}
</FormItem>
</Col>
<Col span={24}>
<Card
title="Selected Scopes"
style={{ width: '100%' }}
>
<div>
{inputVisible && (
<Input
ref={this.saveInputRef}
type="text"
size="small"
style={{ width: 350 }}
value={inputValue}
onChange={this.handleInputChange}
onBlur={this.handleInputConfirm}
onPressEnter={this.handleInputConfirm}
/>
)}
{!inputVisible && (
<Tag
onClick={this.showInput}
style={{ background: '#fff', borderStyle: 'dashed', margin: '5px 0' }}
>
<Icon type="plus" /> New Scope
</Tag>
)}
</div>
{ selectedScopesTags.length > 0 ? (
selectedScopesTags
) : <p>No scopes selected yet.</p> }
</Card>
</Col>
</Row>
</Form>
</Modal>
);
}
}
export default Form.create()(FormModal);
I know that this component is urging for a refactoring, but that's not my job right now. I need to UI test this and validate if everything is working properly.
I'm trying to test if the form fields are rendering properly. I'm using Jest and Enzyme and so far I got this:
describe('Groups modal', () => {
let props;
const groupsModal = () =>
mount(
<FormModal.WrappedComponent {...props} />
)
beforeEach(() => {
props = {
data: null,
scopes: ,
clients: ,
treeData: ,
isEditing: false,
isSaving: false,
onCancel: jest.fn(),
onSave: jest.fn(),
onFilterTreeData: jest.fn(),
visible: true,
form: {
getFieldsError: jest.fn(() => { return {} }),
getFieldDecorator: () => (component) => component
}
};
});
it('should render properly', () => {
const wrapperDivChilds = groupsModal().find('.user-modal').children();
expect(wrapperDivChilds.length).toBeGreaterThanOrEqual(1);
});
describe('form fields', () => {
it('should render name input', () => {
const nameInput = groupsModal().find(Input);
expect(nameInput.length).toBe(1);
});
it('should render clients select', () => {
const clientsSelect = groupsModal().find(Select);
expect(clientsSelect.length).toBe(1);
});
it('should render scopes tree select', () => {
const scopesTreeSelect = groupsModal().find(TreeSelect);
expect(scopesTreeSelect.length).toBe(1);
});
});
});
All of my tests that validate if the inputs were rendered are failing.
As you can see, I tried mocking the form decorator functions, but still no success...
So, my question is: how should I test this component?
reactjs testing jestjs antd ui-testing
I've been struggling with this for months, now. Although there's a lot of speculation on the correct way to test antd wrapped components, none of the suggestions worked for this particular component.
So, I have a component which is a modal with an antd form. In this form, I have a few fields: an input, a select and a tree select, nothing too fancy.
It's basically this:
class FormModal extends React.Component {
static propTypes = {
data: propTypes.object,
form: propTypes.object,
scopes: propTypes.array.isRequired,
clients: propTypes.array.isRequired,
treeData: propTypes.array.isRequired,
isEditing: propTypes.bool.isRequired,
isSaving: propTypes.bool.isRequired,
onCancel: propTypes.func.isRequired,
onSave: propTypes.func.isRequired,
onFilterTreeData: propTypes.func.isRequired,
visible: propTypes.bool.isRequired
}
static defaultProps = {
data: null,
form: {}
}
state = {
selectedScopes: ,
newScopes: ,
inputVisible: false,
inputValue: ''
};
componentDidMount() {
// do stuff
}
handleSave = () => {
// do stuff
}
handleSelectedScopesChange = (event) => {
// do stuff
}
updateTreeSelect = () => {
const { form } = this.props;
const { selectedScopes } = this.state;
form.setFieldsValue({
allowedScopes: selectedScopes
});
}
handleRemoveTag = (removedTag) => {
const selectedScopes = this.state.selectedScopes.filter(scope => scope !== removedTag);
const newScopes = this.state.newScopes.filter(scope => scope !== removedTag);
this.setState({ selectedScopes, newScopes }, this.updateTreeSelect);
}
showInput = () => {
this.setState({ inputVisible: true }, () => this.input.focus());
}
handleInputChange = (e) => {
const inputValue = e.target.value;
this.setState({ inputValue });
}
handleInputConfirm = () => {
const { newScopes, inputValue } = this.state;
let tags = newScopes;
if (inputValue && tags.indexOf(inputValue) === -1) {
tags = [inputValue, ...tags];
}
this.setState({
newScopes: tags,
inputVisible: false,
inputValue: '',
});
}
saveInputRef = input => this.input = input
renderTags = (scopeArrays) => {
const tags = scopeArrays.map(scopeArray =>
scopeArray.map((permition) => {
let scopeType = null;
if (permition.includes('read') || permition.includes('get')) scopeType = 'blue';
if (permition.includes('create') || permition.includes('write') || permition.includes('send')) scopeType = 'green';
if (permition.includes('update')) scopeType = 'gold';
if (permition.includes('delete')) scopeType = 'red';
return (
<Tag
key={permition}
color={scopeType || 'purple'}
style={{ margin: '2px 4px 2px 0' }}
closable
afterClose={() => this.handleRemoveTag(permition)}
>
{permition}
</Tag>
);
})
);
return .concat(...tags);
}
render() {
const {
selectedScopes,
newScopes,
inputValue,
inputVisible
} = this.state;
const {
form,
treeData,
clients,
isEditing,
isSaving,
onCancel,
onFilterTreeData,
visible
} = this.props;
const {
getFieldDecorator,
getFieldsError,
} = form;
const selectedScopesTags = this.renderTags([newScopes, selectedScopes]);
const clientOptions = clients.map(client => (<Option key={client._id}>{client.name}</Option>));
return (
<Modal
className="user-modal"
title={isEditing ? 'Editing Group' : 'Creating Group'}
visible={visible}
onCancel={onCancel}
footer={[
<Button key="cancel" onClick={onCancel}>Cancel</Button>,
<Button
key="save"
type="primary"
loading={isSaving}
onClick={this.handleSave}
disabled={formRules.hasErrors(getFieldsError())}
>
Save
</Button>
]}
>
<Form layout="vertical" onSubmit={this.handleSave}>
<Row gutter={24}>
<Col span={12}>
<FormItem label="Name">
{getFieldDecorator(
'name',
{ rules: [formRules.required, { max: 20, message: 'Group name can't excede 20 characters' }] }
)(
<Input />
)}
</FormItem>
</Col>
<Col span={12}>
<FormItem label="Client">
{getFieldDecorator(
'client', { rules: [formRules.required] }
)(
<Select placeholder="Please select client">
{clientOptions}
</Select>
)}
</FormItem>
</Col>
<Col span={24}>
<FormItem label="Scopes">
{getFieldDecorator(
'allowedScopes'
)(
<TreeSelect
treeData={treeData}
filterTreeNode={onFilterTreeData}
onChange={this.handleSelectedScopesChange}
treeCheckable
dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
showCheckedStrategy="SHOW_PARENT"
searchPlaceholder="Filter by scopes"
className="groups__filter groups__filter--fill"
/>
)}
</FormItem>
</Col>
<Col span={24}>
<Card
title="Selected Scopes"
style={{ width: '100%' }}
>
<div>
{inputVisible && (
<Input
ref={this.saveInputRef}
type="text"
size="small"
style={{ width: 350 }}
value={inputValue}
onChange={this.handleInputChange}
onBlur={this.handleInputConfirm}
onPressEnter={this.handleInputConfirm}
/>
)}
{!inputVisible && (
<Tag
onClick={this.showInput}
style={{ background: '#fff', borderStyle: 'dashed', margin: '5px 0' }}
>
<Icon type="plus" /> New Scope
</Tag>
)}
</div>
{ selectedScopesTags.length > 0 ? (
selectedScopesTags
) : <p>No scopes selected yet.</p> }
</Card>
</Col>
</Row>
</Form>
</Modal>
);
}
}
export default Form.create()(FormModal);
I know that this component is urging for a refactoring, but that's not my job right now. I need to UI test this and validate if everything is working properly.
I'm trying to test if the form fields are rendering properly. I'm using Jest and Enzyme and so far I got this:
describe('Groups modal', () => {
let props;
const groupsModal = () =>
mount(
<FormModal.WrappedComponent {...props} />
)
beforeEach(() => {
props = {
data: null,
scopes: ,
clients: ,
treeData: ,
isEditing: false,
isSaving: false,
onCancel: jest.fn(),
onSave: jest.fn(),
onFilterTreeData: jest.fn(),
visible: true,
form: {
getFieldsError: jest.fn(() => { return {} }),
getFieldDecorator: () => (component) => component
}
};
});
it('should render properly', () => {
const wrapperDivChilds = groupsModal().find('.user-modal').children();
expect(wrapperDivChilds.length).toBeGreaterThanOrEqual(1);
});
describe('form fields', () => {
it('should render name input', () => {
const nameInput = groupsModal().find(Input);
expect(nameInput.length).toBe(1);
});
it('should render clients select', () => {
const clientsSelect = groupsModal().find(Select);
expect(clientsSelect.length).toBe(1);
});
it('should render scopes tree select', () => {
const scopesTreeSelect = groupsModal().find(TreeSelect);
expect(scopesTreeSelect.length).toBe(1);
});
});
});
All of my tests that validate if the inputs were rendered are failing.
As you can see, I tried mocking the form decorator functions, but still no success...
So, my question is: how should I test this component?
reactjs testing jestjs antd ui-testing
reactjs testing jestjs antd ui-testing
edited Jan 10 at 16:24
skyboyer
4,20811333
4,20811333
asked Jan 3 at 18:30
Leticia Costa DiasLeticia Costa Dias
11
11
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
If you want to assert only initially rendered info, you can directly import your wrapped component and do:
const component = mount(<WrappedComponent {...props} form={formMock} />);
On the other hand if you don't want to use mock form or want to assert any logic connected with form-observer-wrappedComponent chain you can do next:
const wrapper = mount(<FormWrapperComponent {...props} />);
// props include anything needed for initial mapPropsToFields
const component = wrapper.find(WrappedComponent);
// Do anything with form itself
const { form } = component.instance().props;
Kinda more time consuming but worked perfectly for me, spent some time to understand how to avoid using form mock. In this case you don't need to mock anything connected with Form itself and if any field is not rendered as you expect you can be sure that problem is in another piece of code.
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54027876%2fhow-to-test-components-wrapped-in-an-antd-form%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
If you want to assert only initially rendered info, you can directly import your wrapped component and do:
const component = mount(<WrappedComponent {...props} form={formMock} />);
On the other hand if you don't want to use mock form or want to assert any logic connected with form-observer-wrappedComponent chain you can do next:
const wrapper = mount(<FormWrapperComponent {...props} />);
// props include anything needed for initial mapPropsToFields
const component = wrapper.find(WrappedComponent);
// Do anything with form itself
const { form } = component.instance().props;
Kinda more time consuming but worked perfectly for me, spent some time to understand how to avoid using form mock. In this case you don't need to mock anything connected with Form itself and if any field is not rendered as you expect you can be sure that problem is in another piece of code.
add a comment |
If you want to assert only initially rendered info, you can directly import your wrapped component and do:
const component = mount(<WrappedComponent {...props} form={formMock} />);
On the other hand if you don't want to use mock form or want to assert any logic connected with form-observer-wrappedComponent chain you can do next:
const wrapper = mount(<FormWrapperComponent {...props} />);
// props include anything needed for initial mapPropsToFields
const component = wrapper.find(WrappedComponent);
// Do anything with form itself
const { form } = component.instance().props;
Kinda more time consuming but worked perfectly for me, spent some time to understand how to avoid using form mock. In this case you don't need to mock anything connected with Form itself and if any field is not rendered as you expect you can be sure that problem is in another piece of code.
add a comment |
If you want to assert only initially rendered info, you can directly import your wrapped component and do:
const component = mount(<WrappedComponent {...props} form={formMock} />);
On the other hand if you don't want to use mock form or want to assert any logic connected with form-observer-wrappedComponent chain you can do next:
const wrapper = mount(<FormWrapperComponent {...props} />);
// props include anything needed for initial mapPropsToFields
const component = wrapper.find(WrappedComponent);
// Do anything with form itself
const { form } = component.instance().props;
Kinda more time consuming but worked perfectly for me, spent some time to understand how to avoid using form mock. In this case you don't need to mock anything connected with Form itself and if any field is not rendered as you expect you can be sure that problem is in another piece of code.
If you want to assert only initially rendered info, you can directly import your wrapped component and do:
const component = mount(<WrappedComponent {...props} form={formMock} />);
On the other hand if you don't want to use mock form or want to assert any logic connected with form-observer-wrappedComponent chain you can do next:
const wrapper = mount(<FormWrapperComponent {...props} />);
// props include anything needed for initial mapPropsToFields
const component = wrapper.find(WrappedComponent);
// Do anything with form itself
const { form } = component.instance().props;
Kinda more time consuming but worked perfectly for me, spent some time to understand how to avoid using form mock. In this case you don't need to mock anything connected with Form itself and if any field is not rendered as you expect you can be sure that problem is in another piece of code.
edited Mar 12 at 13:32
answered Mar 12 at 13:06
LessButBetterLessButBetter
11
11
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54027876%2fhow-to-test-components-wrapped-in-an-antd-form%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown