#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 и дайте мне знать, если это сработает.