Reputation: 1197
I have a component in which the state gets updated depending upon the response from the API call. I am able to test if data returned from the API is being rendered on screen or not. But I don't know how to test that a proper message (i.e errorMessage) is being shown when API call is failing.
Component :
import React, { useState } from "react";
import { getTodos } from "./Api";
interface responseType {
completed: boolean;
id: number;
title: string;
userId: number;
}
const Todo: React.FC = () => {
const [isSuccess, set_isSuccess] = useState(false);
const [errorMessage, set_errorMessage] = useState('');
const [data, set_data] = useState<responseType[]>([]);
const handleFetchData = () => {
getTodos()
.then((response) => {
if (response) {
set_isSuccess(true);
set_data(response.slice(0, 4))
}
})
.catch((error) => {
console.log(error);
set_errorMessage('Failed to fetch data');
});
};
return (
<>
<h2>Demo App</h2>
<button onClick={handleFetchData}>Click</button>
<div>
{isSuccess ?
data.map((val) => val.title) : errorMessage}
</div>
</>
)
}
export default Todo;
In the above code getTodos()
is the function for making the API call. I can test the scenario when API call is successfull. Below is the test file.
import { render, screen, waitFor } from '@testing-library/react';
import Todo from './Todo';
import userEvent from '@testing-library/user-event';
jest.mock('./Api', () => ({
getTodos: jest.fn(() =>
Promise.resolve([
{
completed: false,
id: 1,
title: "a sample item",
userId: 1
}])
)
})
)
it('data fetched successfully', async () => {
render(<Todo />)
const btn = screen.getByRole('button', { name: 'Click' })
userEvent.click(btn);
await waitFor(() => screen.getByText(/a sample item/i));
})
I want to write a similar test case in same file to check if the message 'Failed to fetch data' is rendered on the screen when API call is failed (catch block get excecuted).
Upvotes: 0
Views: 4819
Reputation:
Try promise.reject() instead of resolve() for testing the catch part.
import Todo from './Todo';
import userEvent from '@testing-library/user-event';
jest.mock('./Api', () => ({
getTodos: jest.fn(() =>
Promise.reject(
{
message: "fetch failed"
})
)
})
)
it('data fetched successfully', async () => {
render(<Todo />)
const btn = screen.getByRole('button', { name: 'Click' })
userEvent.click(btn);
await waitFor(() => screen.getByText(/a sample item/i));
})```
Upvotes: 2