Search code examples
javascriptjestjsaxiosaxios-mock-adapter

Expecting an error with axios-mock-adapter


I am trying to test an axios get request with axios-mock-adapter, such that an error is thrown given a status that does not equal 200. However, when I execute the test (see api.test.js), I get the following message:

Error: expect(function).toThrowError(undefined)

Expected the function to throw an error. But it didn't throw anything.

How do I test to make sure that an error is thrown, using axios-mock-adapter using my get and handleResponse methods? Thanks!

api.test.js:

import axios from 'axios';
import MockAdapter from 'axios-mock-adapter';

const handleResponse = (response) => {
  if (response.status !== 200) {
    throw new Error('foo');
  } else {
    return response.data;
  }
};

const get = async (url) => {
  const response = await axios.get(url, {withCredentials: true});
  return handleResponse(response);
};

test('testing that, when making a get request to the appropriate url, an error is thrown ' +
     ' when status !== 200', async () => {
  new MockAdapter(axios)
    .onGet('sampleUrl')
    .reply(500, {data: 'payload'});
  const expectedError = async () => {
    await get('sampleUrl');
  };
  expect(expectedError).toThrowError();
});

Solution

  • The problem I'm seeing in your code is that expect().toThrowError() expects an synchronous exception, but your code is actually rejecting a promise. The bit that may be confusing is that you see throw new Error('foo'); in your handleResponse. That's throwing an exception, true. However, because this code is called by an async function this exception is converted to a promise rejection. So await get('sampleUrl') does not result in a synchronous exception being thrown but in an asynchronous promise rejection.

    Looking at Jest's documentation, it seems to me that you should be doing:

    return expect(expectedError()).rejects.toThrowError();
    

    You need to call expectedError because it is a function that returns a promise, and you need to use .rejects to converts the rejection to a plain exception that can be tested with .toThrowError(). Make sure to return the assertion, or await it. Otherwise you'll have dangling promise.