I've just set up a mock test of an api call but now am wanting to know how I could actually test this mocked data against my component. My api call will render a random set of information hence the mock. I want to render my Weather component and test if the data from the mocked api is being displayed. At the moment I'm just testing the returning values I've mocked at the start of the test.
Here is my test:
import axios from 'axios';
import { fetchWeatherData } from '../../__mocks__/WeatherMocks';
import { render, screen, waitFor } from '@testing-library/react';
import Weather from '../Weather';
jest.mock('axios');
const mockedAxios = axios as jest.Mocked<typeof axios>;
describe('mock api calls', () => {
afterEach(() => {
// jest.resetAllMocks();
});
test('mock returned api data', async () => {
mockedAxios.get.mockResolvedValue({
data: {
result: {
weather: {
forcast: 'Sunny',
max: 28,
min: 17,
description: 'Clear skys all day with a warm summber breaze ariving in the afternoon',
},
},
},
});
const { getByText } = render(<Weather />);
await waitFor(() => {
fetchWeatherData();
expect(
getByText('Clear skys all day with a warm summber breaze ariving in the afternoon'),
).toBeInTheDocument();
expect(getByText('Sunny')).toBeInTheDocument();
});
});
});
and my Weather component:
import axios from 'axios';
import { useEffect, useState } from 'react';
import { IWeather } from '../interfaces/IWeather';
import { MdWbSunny } from 'react-icons/md';
import { IoIosPartlySunny } from 'react-icons/io';
import { BsFillCloudSnowFill } from 'react-icons/bs';
import { Title, Text } from '@mantine/core';
const Weather = () => {
const [weather, setWeather] = useState<IWeather | null>();
const fetchWeatherData = async () => {
const response = await axios.get('http://mock-api-call/weather/get-weather');
setWeather(response.data.result.weather);
};
useEffect(() => {
fetchWeatherData();
}, []);
return (
<div className="container">
<>
<Title order={2}>
{weather?.forcast === 'Sunny' ? (
<MdWbSunny />
) : weather?.forcast === 'Snowing' ? (
<BsFillCloudSnowFill />
) : (
<IoIosPartlySunny />
)}
</Title>
</>
<Text size="xl" data-testid="forcast">
{weather?.forcast}
</Text>
<Text size="lg" data-testid="temp">
Temp: {`${weather?.min} to ${weather?.max}`}
</Text>
<Text size="md" data-testid="description">
{weather?.description}
</Text>
</div>
);
};
export default Weather;
CodePudding user response:
You need to render your component, then check that the DOM generated by the component, when the API call is mocked, contains what the mock returns :
import { render, waitFor } from '@testing-library/react';
import axios from 'axios';
import { fetchWeatherData } from '../../__mocks__/WeatherMocks';
import Weather from '../Weather';
jest.mock('axios');
const mockedAxios = axios as jest.Mocked<typeof axios>;
describe('mock api calls', () => {
afterEach(() => {
// jest.resetAllMocks();
});
test('mock returned api data', async () => {
mockedAxios.get.mockResolvedValue({
data: {
result: {
weather: {
forcast: 'Sunny',
max: 28,
min: 17,
description: 'Clear skys all day with a warm summber breaze ariving in the afternoon',
},
},
},
});
// render the component, get a reference on react-testing-library object
// see https://testing-library.com/docs/react-testing-library/api#render-result
const rtl = render(<Weather />);
// wait for the mocked API call to complete and your component to render
await waitFor(() => {
// now you can assert on the Weather's rendered DOM
expect(rtl.getByText('Clear skys all day with a warm summber breaze ariving in the afternoon').toBeTruthy();
// you should be able to assert on API mocked call
// not sure about the syntax
expect(mockedAxios.get).toHaveBeenCalled();
// assert on other things
expect(...
});
});
});