How to test components wrapped in an antd Form?












0















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?










share|improve this question





























    0















    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?










    share|improve this question



























      0












      0








      0








      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?










      share|improve this question
















      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






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Jan 10 at 16:24









      skyboyer

      4,20811333




      4,20811333










      asked Jan 3 at 18:30









      Leticia Costa DiasLeticia Costa Dias

      11




      11
























          1 Answer
          1






          active

          oldest

          votes


















          0














          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.






          share|improve this answer


























            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
            });


            }
            });














            draft saved

            draft discarded


















            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









            0














            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.






            share|improve this answer






























              0














              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.






              share|improve this answer




























                0












                0








                0







                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.






                share|improve this answer















                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.







                share|improve this answer














                share|improve this answer



                share|improve this answer








                edited Mar 12 at 13:32

























                answered Mar 12 at 13:06









                LessButBetterLessButBetter

                11




                11
































                    draft saved

                    draft discarded




















































                    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.




                    draft saved


                    draft discarded














                    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





















































                    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







                    Popular posts from this blog

                    Monofisismo

                    Angular Downloading a file using contenturl with Basic Authentication

                    Olmecas