我是测试前端应用程序的新手,我只是切换到创建自定义钩子。今天我花了一天的时间,研究这里可用的各种测试选项,并在开始使用Enzyme进行测试之后,我决定从测试库重新开始。
我正在开发一个小型应用程序,该应用程序基本上具有一个使用两个自定义钩子的容器SignUpFormContainer,我想编写一个呈现SignUpFormContainer的测试,检查是否显示了微调器,然后模拟API的响应并检查输出是否正确再次显示。 不幸的是,我还没有成功编写测试。我认为模拟Axios缺少一些东西。
我运行测试时失败,并且文本预期元素为“正在加载...”,而不是“你好”。
有人知道我的考试出了什么问题吗?
谢谢
马修
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");
});
});