1

私は 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 />コンポーネントが渡さ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 |       );

そのため、関数がコンポーネントを通過したことを正しくテストする方法がわかりません。どうすればこれを行うことができますか?

私が機能することがわかった方法が1つありました。これは、次のように関数を渡すことでした<Formik />:

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

そして、ちょうど:

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

問題は、そのような関数を渡したときに、過去に単体テストで問題が発生したことです。また、この方法で TypeScript の型を失います。最初の試行を機能させる方法はありますか」

4

1 に答える 1