This article is going to explain how to perform and test Ajax requests in a React application using Redux and Axios which is a promise based HTTP client.
I like Axios because of the way you can centrally configure the common behaviour for the requests your front-end needs to make and the responses it receives. To take one example, it has the concept of interceptors that allow you to write a single function that can the handle responses such as a 401 unauthorized or 500 exception.
When using Axios I like to create a utility ‘Service’ class to setup the centralised config and ensure all Ajax requests get handled consistently.
It also means calls to Axios are not sprinkled all over the codebase, so I could swap out Axios for an alternative library and I should only need to update this one wrapper class.
In a Redux application, actions are purely functional and thus ‘side-effect free’. So in order to perform Ajax requests you will need middleware such as ‘redux-thunk’. An alternative, that I’ve not used but heard good things of, is redux-loop.
Redux Thunk means you can return a function from your action to delay the dispatch of it, or only dispatch if a condition is met (like the response status is 200).
Once Redux Thunk is installed, you can return a function in your Action as shown by
saveResource in the example below:
Then for any containers that you want to use the action, you need to pass through the dispatch to the function in the
To test the action you can use standard jasmine spy functions:
Then finally to test the Service class:
There are a few bits here to go through here. Firstly I found that when running the specs
I needed to add the babel-polyfill for Promises. I’m using Karma test runner so I needed to add
'node_modules/babel-polyfill/dist/polyfill.js' to the files array in the karma.config.js
Secondly at the top of the spec you’ll notice that jasmine-ajax is imported. This is the official plugin for faking Ajax requests in your Jasmine specs. What I like about this
is that it has no knowledge of Axios. In the
beforeEach it is turned on and
then all Ajax requests triggered in the specs are captured and can be inspected.
Due to the asynchronous nature of the promise, I use
setTimeout to grab the
most recent request and check it was formed correctly. To test the callback
I use the
then function on the promise under test.
A small, but important, detail is the call to
done() – this ensures the test
does not exit early and waits until the asynchronous part of the test is complete
And that’s it! There’s a lot of code there, but once the Service class is setup it should remain pretty much unchanged. Adding additional Ajax requests to your React application actions should be fairly straight forward.