Я новичок в тестировании веб-приложений и просто переключился на создание своих пользовательских хуков. Сегодня я провел день, рассматривая различные варианты тестирования, доступные здесь, и после запуска моих тестов с помощью Enzyme я решил начать все заново с библиотеки тестирования.
Я работаю над небольшим приложением, которое в основном имеет одноКонтейнер SignUpFormContainer с использованием двух пользовательских хуков, и я хочу написать тест, который визуализирует SignUpFormContainer, проверяет, отображается ли счетчик, затем проверяет ответ API и проверяет, отображается ли правильный вывод снова. К сожалению, мне пока не удалось написать тест. Я думаю, что я что-то упускаю из-за фиктивного Аксиоса.
Когда я запускаю тест, он не проходит, и ожидаемый текстовый элемент «Идет загрузка ...» вместо «Привет!».
Кто-нибудь знает, что не так с моим тестом?
Спасибо,
Матье
import React, {useEffect, useState} from 'react';
import SignUpFormComponent from "components/SignUpFormComponent/SignUpFormComponent";
import useForm from "Hooks/useForm/useForm";
import validate from "./SignUpFormValidationRules";
import {Redirect, withRouter} from "react-router";
import {SignUpServices} from "Services/services";
import {Credentials, SignUpFormContainerAdminProps} from "./types";
import useLinkVerification from "Hooks/useVerification/useVerification";
import {IS_EXPIRED, IS_LOADING, IS_VERIFIED} from "constants/verification";
import LoadingPage from "components/LoadingPage/LoadingPage";
import {CLIENT, MEMBER} from "constants/users";
const SignUpFormContainer: React.FC<SignUpFormContainerAdminProps> = (props: SignUpFormContainerAdminProps) => {
const {values, handleChange, handleSubmit, errors} = useForm(signUp, validate);
const {match, history, location} = props;
const [isSubmitBtnDisabled, setDisabled] = useState<boolean>(true);
const [credentials, setCredentials] = useState<Credentials>({token: "", email: ""});
const [step, setStep] = useState<number>(0);
const {verificationStatus} = useLinkVerification({match, history, location});
const userType = location.pathname.startsWith("/client") ? CLIENT : MEMBER;
const [fetchError, setFetchError] = useState<string>("");
useEffect(() => {
if (match.params.token && match.params.email) {
setCredentials({email: match.params.email, token: match.params.token})
}
}, [match.params]);
useEffect(() => {
if (values.country && values.lastName && values.firstName && values.password && values.passwordConfirmation && values.dataManagement) {
setDisabled(false)
} else {
setDisabled(true)
}
}, [values]);
async function signUp() {
setFetchError("");
try {
const signUpServices = new SignUpServices();
await signUpServices.newUserFromInvitation({
email: credentials.email,
token: credentials.token,
firstName: values.firstName as string,
country: values.country as string,
lastName: values.lastName as string,
password: values.password as string
}, userType);
setStep(1)
} catch (error) {
setFetchError("Un compte associé à cette adresse email existe déjà. Veuillez contacter la personne qui vous a envoyé cet email.")
}
}
switch (verificationStatus) {
case IS_LOADING:
return <LoadingPage/>;
case IS_VERIFIED:
return <SignUpFormComponent handleChange={handleChange}
step={step}
fetchError={fetchError}
errors={errors}
state={values} handleSubmit={handleSubmit}
isSubmitBtnDisabled={isSubmitBtnDisabled}/>;
case IS_EXPIRED:
return <Redirect to={"/expired"}/>;
default:
return <Redirect to={"/expired"}/>;
}
};
export default withRouter(SignUpFormContainer)
const useLinkVerification = (props: UseLinkVerificationProps) => {
const {match, location} = props;
const [verificationStatus, setVerificationStatus] = useState<VerificationStatus>(IS_LOADING);
const {email, token} = match.params;
const userType = location.pathname.startsWith("/client") ? CLIENT : MEMBER;
useAsyncEffect(async () => {
try {
const signUpServices = new SignUpServices();
const response = await signUpServices.verifyLink({emailAdress: email, token: token}, userType);
if (response.data) setVerificationStatus(IS_VERIFIED)
} catch (error) {
setVerificationStatus(IS_EXPIRED);
}
}, [email, token, userType]);
return {
verificationStatus
}
};
export default useLinkVerification;
import React, {useEffect, useState} from 'react';
import {SignUpFormState} from "containers/SignUpFormContainer/types";
const useForm = (callback: () => void, validate: (values: {[name:string]: any}) => {[name:string]: any}) => {
const [values, setValues] = useState<SignUpFormState>({
});
const [errors, setErrors] = useState({});
const [isSubmitting, setIsSubmitting] = useState(false);
const handleSubmit = (event: React.ChangeEvent<HTMLFormElement>) => {
if (event) event.preventDefault();
setIsSubmitting(true);
setErrors(validate(values));
};
useEffect(() => {
if (Object.keys(errors).length === 0 && isSubmitting) {
callback();
}
}, [errors, isSubmitting]);
const handleChange = (name: string, value: string | boolean) => {
setValues(values => ({ ...values, [name]: value }));
};
return {
handleChange,
handleSubmit,
values,
errors,
}
};
export default useForm;
import React from "react";
import SignUpFormContainer from "./SignUpFormContainer";
import {cleanup, render, waitForElement} from "@testing-library/react";
import {Router} from "react-router";
import {createMemoryHistory} from "history";
import '@testing-library/jest-dom/extend-expect'
const axiosMock = {
get: jest.fn().mockResolvedValue({data: {}})
};
function renderWithRouter(children: any, historyConf = {}) {
const history = createMemoryHistory(historyConf);
return render(<Router history={history}>{children}</Router>)
}
describe("Test SignUpContainer", () => {
it('should load and render a form', async () => {
axiosMock.get.mockResolvedValueOnce({ data: { greeting: "hello there" } });
const {getByText, getByTestId} = renderWithRouter(<SignUpFormContainer/>);
expect(getByText("Loading...")).toBeInTheDocument();
const resolvedSpan = await waitForElement(() => getByTestId("resolved"));
expect(resolvedSpan).toHaveTextContent("hello there");
});
});