How to test React components with HTTP client (like axios)

When testing wit Jest, the test is working in a command line environment, which mimics the browser. However, this fake browser environment doesn’t allow us to interact with APIs outside of it. Then, how do we make AJAX requests while testing with Jest?

Assuming that you use axios for calling API calls, moxios will be the solution.

First of all, you need to install moxios.

npm install moxios --save-dev

After that, you need to import moxios in your test file(s).

The moxios instance will call install() and stubRequest() in beforeEach, and uninstall() in afterEach().

import moxios from 'moxios'

beforeEach(() => {
    moxios.install();
    moxios.stubRequest('http://example.com/orders/123', {
        status: 200,
        response: {id:123, productName:"blah blah", customerId:456}
    });
})

afterEach(() => {
    moxios.uninstall();
})

With moxios.install(), moxios will be going to intercept requests made by axios.

Then, moxios will mock the URL with stubRequest(). The first argument is the URL you call, and the second argument is the result you expect.

In this way, we can mock the behavior of axios in the testing environment.

However, as far as I’ve learned, moxios does NOT intercept an API call immediately after the call was issued. So, we need to make sure that there is no time gap between the API call and moxios intercepting the API call.

This can be achieved with Jest’s done() and moxios’ wait().

e.g.

import React from 'react';
import { mount } from 'enzyme';
import moxios from 'moxios';
import App from '../components/App';

beforeEach(() => {
    moxios.install();
    moxios.stubRequest('http://example.com/orders/123', {
        status: 200,
        response: {id:123, productName:"blah blah", customerId:456}
    });
})

afterEach(() => {
    moxios.uninstall(); 
})

it('can fetch an order', (done) => {
	const wrapped = mount(<App />);

	wrapped.find('#fetch-order').simulate('click');

	moxios.wait(() => {
		wrapped.update();

		expect(wrapped.find('#order').length).toEqual(1);
		done();

		wrapped.unmount();
	});
});

 

Leave a Reply

Your email address will not be published. Required fields are marked *