Trying to make a simple Axios mock with jest

Viewed 1720

I am trying to understand this example, so the first thing I am trying is removing his axiosConfig.js, so the example looks more like the current case I would like to solve. However I get this error

- Expected
+ Received

  Object {
+   "baseURL": "https://jsonplaceholder.typicode.com/albums",
    "method": "get",
    "url": "/3/photos?_limit=3",
  },

Number of calls: 1

  39 |         const photos = await getPhotosByAlbumID(3);
  40 |         expect(axios.request).toHaveBeenCalled();
> 41 |         expect(axios.request).toHaveBeenCalledWith({ method: 'get', url: '/3/photos?_limit=3' })
     |                               ^
  42 |         expect(photos.length).toEqual(3);
  43 |         expect(photos[0].albumId).toEqual(3)
  44 |     });

Question

Can anyone figure out how to fix the failed test?

If I remove baseURL: 'https://jsonplaceholder.typicode.com/albums' from getPhotosByAlbumId(), but it doesn't make sense to have axios.request() without a baseURL.

I have it online at https://repl.it/@SandraSchlichti/jest-playground#index.js

index.js

const axios = require('axios');

const getPhotosByAlbumId = async (id) => {
    const result = await axios.request({
      baseURL: 'https://jsonplaceholder.typicode.com/albums',
      method: 'get',
      url: `/${id}/photos?_limit=3`
    });
    const { data } = result;
    return data;
};

module.exports = getPhotosByAlbumId;

index.spec.js

const axios = require('axios');
const getPhotosByAlbumID = require('./index');

jest.mock('axios', () => {
    return {
        baseURL: 'https://jsonplaceholder.typicode.com/albums',
        request: jest.fn().mockResolvedValue({
            data: [
                {
                    albumId: 3,
                    id: 101,
                    title: 'incidunt alias vel enim',
                    url: 'https://via.placeholder.com/600/e743b',
                    thumbnailUrl: 'https://via.placeholder.com/150/e743b'
                },
                {
                    albumId: 3,
                    id: 102,
                    title: 'eaque iste corporis tempora vero distinctio consequuntur nisi nesciunt',
                    url: 'https://via.placeholder.com/600/a393af',
                    thumbnailUrl: 'https://via.placeholder.com/150/a393af'
                },
                {
                    albumId: 3,
                    id: 103,
                    title: 'et eius nisi in ut reprehenderit labore eum',
                    url: 'https://via.placeholder.com/600/35cedf',
                    thumbnailUrl: 'https://via.placeholder.com/150/35cedf'
                }
            ]
        })
    }
})

describe('test getPhotosByAlbumID ', () => {
    afterEach(() => jest.resetAllMocks());

    it('fetches photos by album id', async () => {
        const photos = await getPhotosByAlbumID(3);
        expect(axios.request).toHaveBeenCalled();
        expect(axios.request).toHaveBeenCalledWith({ method: 'get', url: '/3/photos?_limit=3' })
        expect(photos.length).toEqual(3);
        expect(photos[0].albumId).toEqual(3)
    });
});
2 Answers

Since in your implementation you're calling axios.request with an object that has baseURL, it doesn't matches your assertion.

So you can either assert that it has to be called with an object that has baseURL

expect(axios.request).toHaveBeenCalledWith({
    baseURL: "https://jsonplaceholder.typicode.com/albums",
    method: "get",
    url: "/3/photos?_limit=3",
});

or that the object the method has been called with has to have these two properties:

expect(axios.request).toHaveBeenCalledWith(
    expect.objectContaining({ method: "get", url: "/3/photos?_limit=3" })
);

working example

I'll recommend U to use Asymmetric Matchers

 expect(axios.request).toHaveBeenCalledWith(
  expect.objectContaining({
    method: 'get',
    url: '/3/photos?_limit=3'
  }))

Sometimes you have a big object and is not necessary to match the exact object you can choose which ones you want to compare.

Another example could be:

expect(mock).toHaveBeenCalledWith(expect.objectContaining({
  postalCode: expect.any(Number)
}));

here your example working https://repl.it/join/ldayfmqz-yoandrycollazo

Related