DEV Community

Discussion on: The only 3 steps you need to mock an API call in Jest

Collapse
 
zaklaughton profile image
Zak Laughton

Thanks for the question! This confused me too, at first, and was a big driver for writing this article. This is the key part that explains it:

When you import a module into a test file, then call it in jest.mock(), you have complete control over all functions from that module, even if they're called inside another imported function.

axios is called in getFirstAlbumTitle(). Axios is not directly called in the test file, but the test file does call getFirstAlbumTitle(), which calls axios. Even though axios is called in a different file, it's still being mocked, because you set up the mock in the test file before calling the function that calls axios.

It might be clearer to see if we define the function in the test file:

// index.test.js
const axios = require('axios');

async function getFirstAlbumTitle() {
  const response = await axios.get('https://jsonplaceholder.typicode.com/albums');
  return response.data[0].title;
}

jest.mock('axios');

it('returns the title of the first album', async () => {
  axios.get.mockResolvedValue({
    data: [
      {
        userId: 1,
        id: 1,
        title: 'My First Album'
      },
      {
        userId: 1,
        id: 2,
        title: 'Album: The Sequel'
      }
    ]
  });

  const title = await getFirstAlbumTitle();
  expect(title).toEqual('My First Album');
});
Enter fullscreen mode Exit fullscreen mode

This makes the connection clearer for the purposes of demonstration, because we can see we are importing axios, including it in getFirstAlbumTitle() function definition, then mocking it. When you import the function instead...

const getFirstAlbumTitle = require('./index');
Enter fullscreen mode Exit fullscreen mode

...axios is still being mocked, even though it's not called directly in the test file.