Mocking an api call in Jest with React Typescript

5.6k Views Asked by At

I'm following some documentation on mocking an api call with Jest, although trying to do it with react.tsx. I've looked at a lot of different stack Q&As and elsewhere online and am not understanding what I am missing from my test file to make my test pass. So far I'm exporting my fetchWeatherData function from my WeatherMocks.tsx:

import axios from 'axios';
    
export const fetchWeatherData = async () => {
  const response = await axios.get('http://mock-api-call/weather/get-weather');
  return response.data.result.weather.forcast;
};

and importing to my test file where I am trying to use this function to mock the data. Weather.test.tsx:

import axios from 'axios';
import { fetchWeatherData } from '../../__mocks__/WeatherMocks';
    
jest.mock('axios');
const mockedAxios = axios as jest.Mocked<typeof axios>;
    
describe('mock api calls', () => {
  afterEach(() => {
    jest.resetAllMocks();
  });
    
  test('return forcast Sunny', 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 forecast = await fetchWeatherData();
    expect(forecast.forcast).toEqual('Sunny');
  });
});

If someone can help me get past this hurdle I would greatly appreciate it as I was told this is a really simple method.

The new testing error

 expect(received).toEqual(expected) // deep equality
    
    Expected: "Sunny"
    Received: undefined
    
      24 |     });
      25 |     const forecast = await fetchWeatherData();
    > 26 |     expect(forecast.forcast).toEqual('Sunny');
         |                              ^
      27 |   });
      28 | });
      29 |
1

There are 1 best solutions below

1
mddg On BEST ANSWER

Second answer

It is failing because in your method you are already returning the weather:

  // ...
  const forecast = await fetchWeatherData();
  const expect(forecast).toEqual('Sunny');
  // ...

Previous answer

What you are doing is already correct, however you are not creating the object structure which you are later accessing:

import axios from 'axios';
import { fetchWeatherData } from '../../__mocks__/WeatherMocks';

jest.mock('axios');
const mockedAxios = axios as jest.Mocked<typeof axios>;

describe('mock api calls', () => {
  afterEach(() => {
    jest.resetAllMocks();
  });

  test('return forcast Sunny', async () => {
    mockedAxios.get.mockResolvedValue({
      // You need to mock all the structure:
      // response -> data -> result -> weather -> forcast
      // You have only:
      // response -> data
      data: {
        result: {
          weather: {
            // Are you sure its forcast and not forecast??
            forcast: 'Sunny',
            max: 28,
            min: 17,
            description: 'Clear skys all day with a warm summber breaze ariving in the afternoon',
          },
        },
      },
    });

    const forecast = await fetchWeatherData();
    expect(forecast).toEqual('Sunny');
  });
});