如何测试使用自定义挂钩中的状态的表单组件?

时间:2019-10-15 13:05:54

标签: reactjs testing jestjs enzyme react-hooks

我创建了一个名为useForm的自定义钩子。 useForm采用一个初始对象,该对象使用useState设置为自己的状态。它返回此状态。该钩子还具有其他功能,例如getDatasubmitData来处理数据检索/发布。它还返回设置状态的handleOnChange函数。

我在名为GeneralInformationForm的表单元素中使用此钩子。此表单具有几个输入,数据检索和发布功能(传递给该钩子以便可以处理错误)。

输入的状态与从useForm钩返回的状态相关联,而我输入的onChange方法是从钩返回的handleOnChange函数。

我的问题是: 当我无法直接设置状态时,如何编写测试以查看表单是否正确提交和检索值?

我应该在输入上触发多个onChange事件以这种方式设置状态吗?我应该以不同的方式处理表格吗?

该钩子存在的原因是在表单之间重用逻辑,特别是onChange和错误设置逻辑。

我正在使用Jest和酶。

GeneralInformationForm.tsx

const GeneralInformationForm = (props: IProps) => {
  useEffect(() => {
    if (props.partnerId) handleGetData();
  }, [props.partnerId]);

  const getData = async () => {
    if (!props.partnerId) return initialState;
    const response = await getPartner(props.partnerId);

    initialState.name.value = response.data.Name;
    initialState.uuid.value = response.data.UUID;
    initialState.token.value = response.data.Token;
    initialState.isAutoClick.value = response.data.IsAutoClickEnabled;

    return initialState;
  };

  useEffect(() => {
    if (props.isSubmitted) handleOnSubmit();
  }, [props.isSubmitted]);

  const submitData = async () => {
    const postObject = {
      Name: state.name.value,
      Token: state.token.value,
      IsAutoClickEnabled: state.isAutoClick.value,
    };

    if (props.partnerId) {
      return editPartner(props.partnerId, postObject, []);
    }

    const response = await createPartner(postObject, []);
    props.setPartnerId(response.data.UUID);
    return response;
  };

  const {
    state,
    handleGetData,
    handleOnChange,
    handleOnSubmit,
  } = useForm(initialState, submitData, props.resetSubmitted, getData);

  return (
    <div className={styles.formContainer}>
      <TextField
        name="name"
        label="Partner name"
        value={state.name.value}
        onChange={handleOnChange}
        margin="normal"
        error={Boolean(state.name.error)}
        helperText={state.name.error}
        variant="outlined"
      />
      <TextField
        name="uuid"
        label="Partner UUID"
        disabled
        value={state.uuid.value}
        onChange={handleOnChange}
        margin="normal"
        error={Boolean(state.uuid.error)}
        helperText={state.uuid.error}
        variant="outlined"
      />
      <TextField
        name="token"
        label="Token"
        disabled={!props.partnerId}
        value={state.token.value}
        onChange={handleOnChange}
        margin="normal"
        error={Boolean(state.token.error)}
        helperText={state.token.error}
        variant="outlined"
      />
      <FormControlLabel
        className={styles.checkbox}
        control={
          <Checkbox checked={state.isAutoClick.value} onChange={handleOnChange} name="isAutoClick" />
        }
        label="Enable Auto-click"
      />
      {!props.partnerId && (
        <Button
          variant="contained"
          onClick={handleOnSubmit}
        >
          Create Partner
        </Button>
      )}
    </div>
  );
};

export default GeneralInformationForm;

const initialState = {
  name: { value: '', error: '' },
  uuid: { value: 'automatically generated', error: '' },
  token: { value: 'automatically generated', error: '' },
  isAutoClick: { value: false, error: '' },
};

useForm.tsx


function useForm(initialState: any, submitData: any, resetSubmitted: any, getData: any) {
  const [state, setState] = useState(initialState);

  const handleOnChange = (event: React.ChangeEvent<HTMLInputElement>) => {
    const { name } = event.target;
    const value = event.target.type === 'checkbox' ? event.target.checked : event.target.value;

    setState((prevState: any) => ({
      ...prevState,
      [name]: { value, error: '' },
    }));
  };

  const handleOnSubmit = async () => {
    const response = await submitData(state);

    if (response === null) {
      // There was no partnerId present so the form could not submit correctly
    }
    if (response.status === 400) {
      handleErrors(response.data);
    }

    // if (response.status === 200) {
    //   handleGetData();
    // }

    resetSubmitted();
  };

  const handleGetData = async () => {
    const retrievedData = await getData();

    setState({ ...retrievedData });
  };

  const handleErrors = (errors: any) => {
    // Set the errors to the state
  };

  return {
    setState,
    state,
    handleOnChange,
    handleOnSubmit,
    handleGetData,
  };
}

0 个答案:

没有答案