Тестирование React Container с React Testing Library с использованием пользовательских хуков и аксиос - PullRequest
0 голосов
/ 30 сентября 2019

Я новичок в тестировании веб-приложений и просто переключился на создание своих пользовательских хуков. Сегодня я провел день, рассматривая различные варианты тестирования, доступные здесь, и после запуска моих тестов с помощью 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");
    });

});

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...