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?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With