Testing api call inside useEffect using react-testing-library

限于喜欢 提交于 2020-07-21 03:52:11

问题


I want to test api call and data returned which should be displayed inside my functional component. I created List component which performs api call. I would like the returned data to be displayed in the component and I use the useState hook for this. Component looks like this:

const List: FC<{}> = () => {
    const [data, setData] = useState<number>();
    const getData = (): Promise<any> => {
        return fetch('https://jsonplaceholder.typicode.com/todos/1');
    };

    React.useEffect(() => {
        const func = async () => {
            const data = await getData();
            const value = await data.json();
            setData(value.title);
        }
        func();
    }, [])

    return (
        <div>
            <div id="test">{data}</div>
        </div>
    )
}

I wrote one test in which I mocked the fetch method. I check if the fetch method has been called and it actually happens. Unfortunately, I don't know how I could test the value returned from response. When I try console.log I just get null and I'd like to get 'example text'. My guess is that I have to wait for this value returned from Promise. Unfortunately, despite trying with methods act and wait, I don't know how to achieve it. Here is my test:

it('test', async () => {
    let component;
    const fakeResponse = 'example text';
    const mockFetch = Promise.resolve({json: () => Promise.resolve(fakeResponse)});
    const mockedFetch = jest.spyOn(window, 'fetch').mockImplementationOnce(() => mockFetch as any )
    await wait( async () => {
        component = render(<List />);
    })
    const value: Element = component.container.querySelector('#test');
    console.log(value.textContent);
    expect(mockedFetch).toHaveBeenCalledTimes(1);
})

I would be really thankful for any suggestions.

Edit.

Also tried with waitForElement. Still receiving null value.

const List: FC<{}> = () => {
    const [data, setData] = useState<string>('test');
    const getData = (): Promise<any> => {
        return fetch('https://jsonplaceholder.typicode.com/todos/1');
    };

    React.useEffect(() => {
        const func = async () => {
            const data = await getData();
            const value = await data.json();
            setData(value.title);
        }
        func();
    }, [])

    return (
        <div>
            <div data-testid="test" id="test">{data}</div>
        </div>
    )
}

and updated test:

it('test', async () => {
    const fakeResponse = 'example text';
    const mockFetch = Promise.resolve({json: () => Promise.resolve(fakeResponse)});
    const mockedFetch = jest.spyOn(window, 'fetch').mockImplementationOnce(() => mockFetch as any )
    const { getByTestId } = render(<List />);
    expect(getByTestId("test")).toHaveTextContent("test");
    const resolvedValue = await waitForElement(() => getByTestId('test'));
    expect(resolvedValue).toHaveTextContent("example text");
    expect(mockedFetch).toHaveBeenCalledTimes(1);
})

来源:https://stackoverflow.com/questions/59892259/testing-api-call-inside-useeffect-using-react-testing-library

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!