Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

react-hook-form submit does not pick up changeText from jest test

I have the following 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>

I am testing the submission and the call to firebase.auth().signInWithEmailAndPassword using jest in the following test:

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 = "[email protected]";
  const password = "password";
  fireEvent.changeText(emailInput, email);
  fireEvent.changeText(passwordInput, password);
  fireEvent.press(submitButton);

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

where I've mocked out signInWithEmailAndPassword as a jest.fn().

When I run this test, it fails with:

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

Expected: "[email protected]", "password"
Received: undefined, undefined

And I noticed the console.log(data) I have in my onSubmit function prints out:

console.log
  {}

which means no text was picked up.

How do I go about testing this form?

like image 320
Richard Avatar asked Nov 07 '22 04:11

Richard


1 Answers

I think the reason why it returns undefined for you is that you are trying to test asynchronous behaviour in a sync way. I would suggest using Promises in your onSubmit method to wait for the firebase auth call to finish.

Something like this could work

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);
    });
};

This would then ensure that you are waiting for the sign in to happen.

In your test, I would mock the firebase to something like this

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

And then in your test, you would also need to use waitFor() to wait for the sign in to happen so then you can check your results. Something like this could work

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

I haven't tested it myself but try the idea of using async and Promises and let me know if that works.

like image 163
Mantas Astra Avatar answered Dec 07 '22 20:12

Mantas Astra