Как проверить компонент, заданный функцией родительского компонента в React (Native) с Jest и Enzyme? - PullRequest
0 голосов
/ 05 октября 2018

Я создаю приложение React Native и использую Jest и Enzyme для своих модульных тестов.Кроме того, я использую TypeScript.

Я строю следующую форму, используя Formik .

import strings from "./strings";
import styles from "./styles";
import { strings as loginStrings } from "../../screens/Login";
import { Formik, FormikActions, FormikProps } from "formik";
import React, { Component } from "react";
import { View } from "react-native";
import { Button, Input } from "react-native-elements";
import { NavigationScreenProp } from "react-navigation";
import { object as yupObject, string as yupString } from "yup";

export interface FormValues {
  email: string;
  password: string;
}

export interface Props {
  navigation: NavigationScreenProp<any, any>;
}

export default class LoginForm extends Component<Props, object> {
  handleSubmit = (values: FormValues, formikBag: FormikActions<FormValues>) => {
    // ... api calls and stuff
  };

  renderForm = ({
    values,
    handleSubmit,
    setFieldValue,
    touched,
    errors,
    setFieldTouched,
    isValid,
    isSubmitting
  }: FormikProps<FormValues>) => (
    <View style={styles.container}>
      // ... two inputs and a button
    </View>
  );

  render() {
    return (
      <Formik
        initialValues={{ email: "", password: "" }}
        onSubmit={(values: FormValues, formikBag: FormikActions<FormValues>) =>
          this.handleSubmit(values, formikBag)
        }
        validationSchema={yupObject().shape({
          email: yupString()
            .email(strings.invalidEmailFormat)
            .required(strings.emailRequired),
          password: yupString()
            .min(8, strings.passwordMinLength)
            .required(strings.passwordRequired)
        })}
        render={(formikBag: FormikProps<FormValues>) => this.renderForm(formikBag)}
      />
    );
  }
}

Как вы можете видеть, это просто простая форма.Теперь я хочу проверить, что <Formik /> компонент get прошел renderForm() и handleSubmit, поэтому я написал следующий тест:

it("should be passed the component's handleSubmit function for onSubmit", () => {
  expect(wrapper.find("Formik").prop("onSubmit")).toEqual(
    (values: FormValues, formikBag: FormikActions<FormValues>) =>
      wrapper.instance().handleSubmit(values, formikBag)
  );
});

И то же самое для renderForm().К сожалению, это приводит к ошибке:

● LoginForm › rendering › should be passed the component's handleSubmit function for onSubmit

    expect(received).toEqual(expected)

    Expected value to equal:
      [Function anonymous]
    Received:
      [Function onSubmit]

    Difference:

    - Expected
    + Received

    - [Function anonymous]
    + [Function onSubmit]

      28 |
      29 |     it("should be passed the component's handleSubmit function for onSubmit", () => {
    > 30 |       expect(wrapper.find("Formik").prop("onSubmit")).toEqual(
         |                                                       ^
      31 |         (values: FormValues, formikBag: FormikActions<FormValues>) =>
      32 |           wrapper.instance().handleSubmit(values, formikBag)
      33 |       );

Так что я не уверен, как правильно проверить, что функция была передана компоненту.Как можно это сделать?

Был один способ, который я нашел, который работал: передача функций на <Formik /> следующим образом:

onSubmit={this.handleSubmit}
render={this.renderForm}

А потом просто:

expect(wrapper.find("Formik").prop("onSubmit)).toEqual(wrapper.instance().onSubmit)

Дело в том, что у меня были проблемы с моими модульными тестами в прошлом, когда я просто передавал такую ​​функцию.Также таким образом я теряю типы TypeScript.Есть ли способ заставить мою первоначальную попытку работать "

1 Ответ

0 голосов
/ 05 октября 2018

Когда вы определяете эту анонимную функцию, вы, по сути, создаете новую, поэтому она никогда не будет равна той, которую использует рендер для внутреннего использования.Вы можете сохранить его как часть объекта и проверить на равенство ссылок (это то, что вы предложили, работает):

expect(wrapper.find("Formik").prop("onSubmit)).toEqual(wrapper.instance().onSubmit)

Другой вариант - смоделировать handleSubmit и проверить,handleSubmit вызывается при нажатии кнопки Submit, что, на мой взгляд, является более разумным тестом.

// set handleSubmit to our fake mock function
wrapper.instance().handleSubmit = jest.fn();
wrapper.update();
// Here you need to simulate a click to submit form
// I don't know how your input looks like
// but it will be similar to
inp.simulate('click')
// expect our mock function to have been called at least once
expect(wrapper.instance().handleSubmit).toHaveBeenCalledTimes(1);
...