0

我想在第一次渲染组件时使用 react-testing-library 进行单元测试,从 API 获取一些信息。

所以我正在使用 setupServer 来模拟 API 并使用 REST 发送虚拟数据,但是组件中只有加载程序,并且 setupServer 无法正常工作

我该如何解决这个问题?

detail.tsx

import React, { FC, useEffect, useState } from 'react';
import { RouteComponentProps, useHistory, withRouter } from 'react-router-dom';
import {
    actorInfo,
    detailMovie,
    movieInfo,
    popularResponseType,
} from '../../types';
import { fetcher, } from '../../utils/request';
import * as S from './styles';
import * as C from '../../utils/constants';
import Loader from '../Loader';

interface movieID {
    id: string;
}
const Detail: FC<RouteComponentProps<movieID>> = ({ match }) => {
    const [detail, setDetail] = useState<detailMovie>();
    const [isLoading, setIsLoading] = useState(false);
    const [error, setError] = useState(false);

    useEffect(() => {
        const getData = async () => {
            setIsLoading(true);
            const movieDetail: detailMovie = await fetcher(`https://api.themoviedb.org/3/movie/343611{API_KEY}&language=kr-KR`);
            setDetail(movieDetail);

            setIsLoading(false);
        };
        getData();
    }, []);
    if (error) {
        return <p>something went wrong</p>;
    }
    return ( isLoading ? (
       <Loader />
)
        <S.Container>
            <S.IntroduceContainer>
                {detail ? (
                    <S.Poster src={`${C.IMAGE_URL_W500}/${detail?.poster_path}`} />
                ) : (
                    <S.Poster />
                )}
                <S.InfoContainer>
                    <S.Title>{detail?.title}</S.Title>
                    <S.RunningTime>{`${detail?.runtime}분`}</S.RunningTime>
                    <S.Description>{detail?.overview}</S.Description>
                </S.InfoContainer>
            </S.IntroduceContainer>           
        </S.Container>
    );
};

export default withRouter(Detail);


detail.test.js

import React from 'react';
import { render, waitFor, screen } from '@testing-library/react';
import { rest } from 'msw';
import { setupServer } from 'msw/node';
import Detail from '../index';
import movieDetailDummy from '../../../dummy/movieDummy';
import { Route, MemoryRouter } from 'react-router-dom';
import { act } from 'react-dom/test-utils';
import { API_KEY, API_URL_MOVIE } from '../../../utils/constants';

const server = setupServer(
    rest.get(`https://api.themoviedb.org/3/movie/343611{API_KEY}&language=kr-KR`, (req, res, ctx) => {
        return res(ctx.status(200), ctx.json(movieDetailDummy));
    })
);
beforeAll(() => server.listen());
afterAll(() => server.close());
afterEach(() => server.resetHandlers());

const renderComponenet = ({ movieID }) =>
    render(
        <MemoryRouter initialEntries={[`/detail/${movieID}`]}>
            <Route path="/detail/:id">
                <Detail />
            </Route>
        </MemoryRouter>
    );

describe('<Detail />', () => {
    it('get movieDetail from tmdb', async () => {
        act(() => {
            renderComponent({ movieID: 343611 });
        });
        await waitFor(() => screen.getByText('잭 리처: 네버 고 백'));
    });
});

fetcher

export const fetcher = async (url: string) => {
    const response = await fetch(url);
    if (!response.ok) {
        const error = new Error('Error while fetching the data');
        error.message = await response.json();
        throw error;
    }
    const result = await response.json();
    return result;
};
4

0 回答 0