Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Trying to make a simple Axios mock with jest

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)
    });
});
like image 835
Sandra Schlichting Avatar asked Mar 01 '23 22:03

Sandra Schlichting


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

like image 59
Teneff Avatar answered Mar 05 '23 17:03

Teneff


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

like image 37
Yoandry Collazo Avatar answered Mar 05 '23 17:03

Yoandry Collazo