Как проверить компонент формы, который использует состояние из пользовательского хука? - PullRequest
0 голосов
/ 15 октября 2019

Я создал пользовательский хук с именем useForm. useForm принимает исходный объект, который он устанавливает в свое собственное состояние, используя useState. Это возвращает это состояние. Хук также принимает другие функции, такие как getData и submitData для обработки извлечения / публикации данных. Он также возвращает функцию handleOnChange, которая устанавливает состояние.

Я использую этот хук внутри элемента формы с именем GeneralInformationForm. Эта форма имеет несколько функций ввода, извлечения данных и публикации (которые передаются в ловушку, чтобы она могла иметь дело с ошибками).

Состояние входов связано с состоянием, которое возвращается из ловушки useForm, а метод onChange моего ввода - это возвращенная функция handleOnChange из ловушки.

Myвопрос в том, как мне написать тесты, чтобы увидеть, правильно ли моя форма отправляет и получает значения, когда я не могу напрямую установить состояние?

Должен ли я запускать несколько событий onChange на входах, чтобы установить состояниетуда? Должен ли я обрабатывать свою форму иначе?

Причина, по которой существует эта ловушка, заключается в том, чтобы повторно использовать логику между формами, в частности onChange и логику установки ошибок.

Я использую Jest и Enzyme.

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,
  };
}
...