Building React-Redux application by TDD

Kunal Hire
ReactFoo
Published in
5 min readApr 8, 2018

JavaScript frameworks have gained so much popularity during past few years. I remember my initial coding days when I used to be a server side developer and working on UI was not my cup of tea. I must say, the rise of frameworks like AngularJS raised my interest in front-end development.

AngularJS is full-fledged MV* framework, so testing the code or rather TDDing an Angular application becomes easy with integrated support of testing libraries like Jasmine and and runner like Karma. However, React is not a framework, its a library. It gives us the flexibility of use but at the same time TDDing React application becomes tricky and introduction of Redux adds more complexity to it.

Today we are going to build the React-Redux application by TDD. For this case study, we will build a simple Leave Management System dashboard. I have already built the leave form. It stores the record in the database whenever it is submitted. The code can be found here. Here we are going to build the dashboard which will show the list of applied leaves.

Story #1 — As an employee, I should be able to view all the leaves that I have applied so that I can plan my work and vacations.

Approach

We will build the application using facebook’s create-react-app. Following elements are involved in the typical react-redux application. We will build them using TDD.

  1. Components
  2. Containers
  3. Reducers
  4. Actions

create-react-app gives us the basic component but with no packaging structure. We will modify the project skeleton as per the domain of our application. At this point the project skeleton is looking like this-

Note that, we have removed the unnecessary code as well. We will use enzyme as primary testing library and mocha as test runner.

When I start TDDing react-redux app, I try to follow specific order of adding tests and code for the component. Generally I follow bottom-up approach i.e. start building components in the following order — actions-reducers-containers-components. One can change the order as per preference.

Let’s start with writing tests for actions-

We will add a test case to make an API call to fetch the leaves-

We have mocked the server call using nock. Here we assert that whenever ‘fetchLeaves’ is called, it should dispatch two actions- 1. LEAVE_FETCHING action — this is to show spinner till the time promise gets resolved. 2. LEAVES_FETCHED action — This is to update store with fetched leaves. At this moment, the test case is red, lets add a code to make it green.

We have not handled the error scenario yet. Let’s do that-

Note that, we still need the spinner even if the API is going to return an error. When it does so, we are expecting the LEAVE_ERROR action to be called. Lets add the code to make it green by adding the dispatch in the catch block.

At this point of time, we are sure that whenever fetchLeaves() is called it will make an API call and set leaves or error based on response status.

Let’s build the reducer-

Writing tests for reducer is the easiest task in the react-redux application. Here we are going to invoke the reducer with LEAVES_FETCHED action and expect that the leaves are updated in the store.

We have not reduced the LEAVES_FETCHED action yet. Lets do that to make the test green. We will add a case in the reducer to handle this ‘type’ of action.

Bingo!! its green. However, we have not handled the error action yet. Here it comes-

At this point, we are sure that whenever fetchLeaves API is called, its response data i.e. leaves are stored in the redux store.

Let’s build the container now-

We are going to build the dashboard container. It will pass the fetchLeaves method and leaves from the store as props to the connected component i.e. dashboard.jsx. The way I test it, is by making an attempt to call the fetchLeaves function, which should be available in the props of mounted enzyme wrapper. We can assert on the actions being dispatched when it is invoked.

If we run above test, it will fail as it will not find fetchLeaves function in the props. Lets add this function in mapDispatchToProps on the container.

And.. its green!!

Let’s do the same trick for the leaves.

Here we need to add leaves in the mapStateToProps.

We are done with the container. Now the final task.

Let’s build the component.

We will call the fetchLeaves method from props, as the component is being mounted. Here will will use React lifecycle hooks to do this.

Here fetchLeavesStub is the stub created using sinon. Lets add the code to make it green. We will call the fetchLeaves from componentDidMount() lifecycle method.

Our plan is to show the list of leaves in the tabular form. We will use table from react-bootstrap.

Our leave has four fields — fromDate, toDate, reason and type. Lets add a test case to have these four headers in the table.

Here, we are trying to find the thead tag an tr in it. Once found, we are asserting the four headers and the texts they have rendered. Lets add the code for it.

By this time, if we refresh the browser we should have-

  1. An API call to be made to fetch the leaves.
  2. The leaves to be updated in the store.
  3. The headers to be rendered in the table.

We do not have the list of leaves yet. Lets get it on the dashboard.

As you have guessed, we will add the tbody tag and render the leaves which are available in the props.

Bingo!! All green and our dashboard is ready. If we refresh the page on the browser, we should have list of the leaves in the tabular form.

Thanks for reading this article. Your feedback and suggestions to make it better are much appreciated. Have a happy coding!!

Originally published at medium.com on April 8, 2018.

--

--