react-hook-form submit не получает текст изменений из jest test

#jestjs #react-hook-form

#jestjs #react-hook-form

Вопрос:

У меня есть следующее react-native-form :

 const { register, handleSubmit, setValue, errors } = useForm();

const onSubmit = (data) => {
  console.log(data);
  return firebase
    .auth()
    .signInWithEmailAndPassword(data.email, data.password)
    .then((info) => {
      console.log(info.additionalUserInfo.profile);
    })
    .catch((err) => {
      console.error(err);
    });
};

  <View>
    <TextInput
      placeholder="Email"
      testID="email-input"
      onChangeText={(t) => setValue("email", t)}
      style={styles.loginTextInput}
    ></TextInput>
    <TextInput
      secureTextEntry={true}
      testID="password-input"
      placeholder="Password (min. 8 characters)"
      onChangeText={(t) => setValue("password", t)}
      style={styles.loginTextInput}
    ></TextInput>
    <TouchableOpacity
      onPress={handleSubmit(onSubmit)}
      testID={"login-email-button"}
      style={[styles.loginButton, styles.loginEmailButton]}
    >
      <Text style={styles.buttonText}>Login with Email</Text>
    </TouchableOpacity>
  </View>
  

Я тестирую отправку и вызов firebase.auth().signInWithEmailAndPassword using jest в следующем тесте:

 test("submit works", async () => {
  const { getByPlaceholderText, getByTestId, getByText } = render(
    <EmailLogin />
  );
  const emailInput = getByTestId("email-input");
  const passwordInput = getByTestId("password-input");
  const submitButton = getByTestId("login-email-button");

  const email = "foo@email.com";
  const password = "password";
  fireEvent.changeText(emailInput, email);
  fireEvent.changeText(passwordInput, password);
  fireEvent.press(submitButton);

  expect(firebase.auth().signInWithEmailAndPassword).toHaveBeenCalledWith(
    email,
    password
  );
});
  

где я высмеивал signInWithEmailAndPassword как jest.fn() .

Когда я запускаю этот тест, он завершается неудачей с:

 expect(jest.fn()).toHaveBeenCalledWith(...expected)

Expected: "foo@email.com", "password"
Received: undefined, undefined
  

И я заметил console.log(data) , что у меня в моей onSubmit функции выводится:

 console.log
  {}
  

это означает, что текст не был получен.

Как мне приступить к тестированию этой формы?

Комментарии:

1. Вы также используете enzyme? с этим будет намного проще

2. Можете ли вы показать, как вы издеваетесь над firebase ?

Ответ №1:

Я думаю, причина, по которой он возвращает undefined для вас, заключается в том, что вы пытаетесь протестировать асинхронное поведение способом синхронизации. Я бы предложил использовать Promises в вашем onSubmit методе, чтобы дождаться завершения firebase auth вызова.

Что-то вроде этого может сработать

 const onSubmit = async (data) => {
  console.log(data);
  return await firebase
    .auth()
    .signInWithEmailAndPassword(data.email, data.password)
    .then((info) => {
      console.log(info.additionalUserInfo.profile);
    })
    .catch((err) => {
      console.error(err);
    });
};
  

Это гарантирует, что вы ожидаете, когда произойдет вход в систему.

В вашем тесте я бы смоделировал firebase примерно так

 jest.mock('firebase', () => ({
    auth: jest.fn().mockReturnThis(),
    signInWithEmailAndPassword: jest.fn(),
   })
);
  

И затем в вашем тесте вам также нужно будет использовать waitFor() , чтобы дождаться входа в систему, чтобы вы могли проверить свои результаты. Что-то вроде этого может сработать

 await waitFor(() => expect(firebase.auth().signInWithEmailAndPassword).toHaveBeenCalledWith(
    email,
    password
  ););
  

Я сам его не тестировал, но попробуйте идею использования async и Promises и дайте мне знать, если это сработает.