How to mock and test Axios rejected promise?

Viewed 5623

I created a class called API and it's a simple wrapper around Axios

export class API {    
  static get = async (route: string, version: string = API_VERSION) => {
    try {
      return await axios.get(`${BASE_URL + version}${route}`);
    } catch (error) {
      throw error;
    }
  };
}

I'm trying to test the catch branch of the get method:

I tried:

describe('API Throws Errors', () => {
  beforeEach(() => {
    // axios.get.mockImplementation(() => Promise.reject('rejected'));
    jest.mock('axios', () => ({
      get: jest.fn().mockReturnValue(Promise.reject('error'))
    }));
  });

  it('get fails', async () => {
    await expect(() => {
      API.get(GROUPS.url());
    }).rejects.toEqual('error');
  });

  afterEach(() => {
    jest.clearAllMocks();
  });
});

enter image description here

2 Answers

You can mock behaviour of axios.get by using jest.mock. Put the below code above the describe section:

jest.mock('axios', () => ({
  get: jest.fn().mockReturnValue(Promise.reject('error'))
}));

And you test the error like below:

it('get fails', async () => {
    await expect(API.get("bad_url")).rejects.toEqual('error');
});

Exact Code

jest.mock('axios', () => ({
    get: jest.fn().mockReturnValue(Promise.reject('error')),
}));

describe('API Throws Errors', () => {
    it('get fails', async () => {
        await expect(API.get(GROUPS.url())).rejects.toEqual('error');
    });
});

Note:

If you have another test case that shouldnt be failed, you can just mock it to return Promise.resolve(). Or you can just simple clear the mock.

describe('API Throws Errors', () => {
    it('get fails', async () => {
        await expect(API.get(GROUPS.url())).rejects.toEqual('error');
    });
    
    it('should success', async () => {
        Axios.get.mockReturnValue(Promise.resolve(SOME_VALUE));
        await expect(API.get(GROUPS.url())).resolves.toEqual(SOME_VALUE);
    });
});

toThrowError() is supposed to be asserted against a function and not result because if an error happens on function call, expect doesn't have a chance to be evaluated. It's applicable only to regular functions where an error is thrown. It's not applicable to async functions because they don't throw an error but return a result, which rejected promise.

rejects.toThrowError() construction is a way how rejected promise can be asserted, an assertion needs to be provided with a promise instead of a function that returns it:

await expect(API.get("bad_url")).rejects.toThrowError();
Related