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.
Second Attempt
Also tried using data-testid="test"
and waitForElement
, but still receiving null value.
updated component deltas:
const List: FC<{}> = () => {
- const [data, setData] = useState<number>();
+ 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 id="test">{data}</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);
})