Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mock Axios to test .catch()

I have been trying to write tests to test a axios call but now need to test the catch part.

I have been able to do the then by mocking axios like so but can't seem to get a way to test catch. I have followed many different examples from stack overflow and the web.

jest.mock('axios', () => jest.fn(() => Promise.resolve({ data: mockData })));

but that will always return a good result so can't test the catch. The bit of code I want to test is: goToUrl() is just a window.location.assign(url) but imported.

fetchBundlesFromApi(params)
  .then(({ data: { bundles } }) => {
    updateBundles(bundles);
    this.setState({ showUpdatingPrices: false });
  })
  .catch(() => goToUrl(bundlesUrl));

In my test for .then() part I do this:

const fetchedBundles = await fetchBundlesFromApi(
  '?params',
);
expect(fetchedBundles.data).toEqual(mockData);

However if I follow examples like this one Mocking Axios with Jest in React - mock function not being called I can't manually mock get if I put a mock axios file in a folder __mocks__ then a lot of the test suit fails so I just want to mock it in this one test file.

here is one of the examples I tried doing:

    jest.mock('axios', () => ({
  get: () => jest.fn(() => Promise.resolve({ data: mockData })),
  default: () => jest.fn(() => Promise.resolve({ data: mockData })),
}));

but the tests error with TypeError: (0 , _axios.default) is not a function

EDIT:

Here is my fetchBundlesApi function:

const fetchBundlesFromApi = params => axios(`${bundleRoute}/bundles${params}`);

EDIT: catch test

    it('should redirect if api fails', async () => {
    const networkError = new Error('Some network error');
    axios.mockRejectedValueOnce(networkError);
    const goToUrl = jest.fn();
    let error;

    try {
      await fetchBundlesFromApi('?params');
    } catch (err) {
      error = err;
    }

    expect(error).toEqual(networkError);
    expect(goToUrl).toHaveBeenCalled();
  });

in my component I import goToUrl like so:

import { goToUrl } from 'Helpers';

like image 717
saunders Avatar asked Nov 07 '19 11:11

saunders


1 Answers

You can make use of Jests ability to pop implementations off once they've run i.e. mockImplementationOnce and friends.

import axios from 'axios';

jest.mock('axios');

// default implementation
axios.get.mockResolvedValue(mockedData);

describe('#fetchBundlesFromApi', () => {
  it('returns data from API', async () => {
    const fetchedBundles = await fetchBundlesFromApi('?params');
    expect(fetchedBundles.data).toEqual(mockData);
  });
  it('redirects on failure', () => {
    // override behaviour for this one call
    axios.get.mockRejectedValueOnce();
    // verify your failure test
  });
});
like image 68
James Avatar answered Sep 21 '22 06:09

James