Unit Testing React components that use Redux

React.js is build to make it easy to Unit Test, and there is plenty of information on how to do this. However as you build more complex applications and employ a store pattern like Redux then things get a little more complicated. This article goes through the issues you need to consider and is supported by a full set of open-source examples on GitHub.

This article is the forth in the series I am writing about creating a React.js samples that are a good starting point for real-world, production-ready applications with full React.js build, test, and deploy capabilities. The other articles in the series are:

  1. Templates for building React.js front-ends in ASP.NET Core and MVC5
  2. Using a Redux store in your React.js application
  3. Adding mocking to React.js Unit Tests
  4. This article: Unit Testing React components that use Redux

The aims of this article

  • Choosing the right React Testing Library to handle Redux.
  • How to test React components that uses Redux.
  • What to do about nested components that use Redux.
  • How to test events when Redux is involved.
  • Quick aside on other decorators like DragAndDrop.

I’m going to assume you at least know what React is and what Redux does. If you don’t know React try these article links [1, 2, 3]. I would also really recommend the book “Pro React”, which helped me a lot. If you don’t know what Redux is and why it is useful I cover that in my second article, Using a Redux store in your React.js application.

Note: One word of warning:  React.js is still changing and articles and books get out of date. This article and open-source AspNetReactSamples on GitHub uses React version 15.0.2  and Redux 3.5.2 (see package.json for full list).

Quick introduction

I had time between projects and I wanted to create a solid foundation for the development of React.js applications. In my first article I describe the tool chain that is needed to build and test React.js applications. As I am a full stack developer focused on Microsoft’s ASP.NET for the server side I build around that (Note: you don’t need any knowledge of ASP.NET to understand this article – its all about React.js).

In my first article I describe the Unit Test setup. So you don’t have to wade through the article here is a summary:

  • I chose Mocha as my test framework. Facebook recommend Jest for Unit Testing React, but a number of posts [1, 2, 3] said Jest was slow and Mocha was better. I have also used Mocha successfully in the past, which gave me confidence in this approach.
  • I used Karma as my test runner. Most people do and I have used it before.
  • I run my Unit Tests inside a real browser, Chrome, rather than a phantom browser so I can debug.
  • I used AirBnB’s Enzyme React testing utility. More on this later.
  • I added NPM scripts in the ReactWebPack.Core’s package.json file so that the tests could be run in same way as the build.

Choosing the React Testing Library

There are a number of unit testing libraries for React. The obvious one is React’s one ReactTestUtils. However I found ReactTestUtils didn’t have great documentation and it has some problems with Redux, e.g. ReactTestUtils doesn’t always seem to like the Redux’s Provider class, which is uses to pass in the Redux information to the React Components. Maybe there is a way to fix it, but I didn’t fine one.

Thankfully I found the excellent Enzyme React testing utility which is very well documented and also works with Redux. For the rest of this article I will use Enzyme.

Note: I do go through this in more detail later, but if you are an expert and want to just ‘look at the code’ to see how ReactTestUtils and Enzyme handle Redux connected components then look at the ConnectedClasses.test.js . I have commented on the ReactTestUtils tests that fail.

Testing a React components that uses Redux.

a: single, non-nested components

I created some very simple classes to check out the best way to test React components that use Redux. Let’s start with the simplest – InnerConnect. The content of this module is:

 
import React, {Component} from 'react';
import { connect } from 'react-redux';

export class InnerConnect extends Component {
    render () { return 
       <h2>
         Inner.dispatch {
           this.props.dispatch === undefined 
              ? 'undefined' : 'defined' }
      </h2>
    }
}
export default connect()(InnerConnect)

Note: For those not familiar with Redux the code above has the minimum it needs to get access to Redux. The connect()(InnerConnect) on the last line adds the property dispatch to the props. Normal use of Redux by a component would include more Redux code.

Redux’s documentation on Writing Tests suggests you export the React component class as well as the default, which should be the Class used (decorated by) in a connect() method.

Now let me give you a segment of the file ConnectedClasses.test.js which does a simple test with and without linking to Redux (or in this case redux-mock-store).

//... various includes but especially the one below
import InnerConnectConnected, {InnerConnect} 
    from '../../localSrc/InnerConnect';
describe('mount', () => {
    it('InnerConnect, no connect', () => {
        const wrapper = mount(<InnerConnect />);
        expect(wrapper.find('h2').length).toBe(1);
        expect(wrapper.find('h2').text())
           .toBe('Inner.dispatch undefined');
    });
    it('InnerConnectConnected, with connect', () => {
        const mockStore = configureStore([]);
        const store = mockStore({});
        const wrapper = mount(<Provider store={store}>
            <InnerConnectConnected />
        </Provider>);
        expect(wrapper.find('h2').length).toBe(1);
        expect(wrapper.find('h2').text())
            .toBe('Inner.dispatch defined');
    });
    //... more tests left out

The first test tests the InnerClass without the connect statement. The second test tests the default export, which contains the class decorated by the Redux connect method. In the tests I use enzyme’s mount which does a full DOM rendering. You can see the first test says this.props.dispatch is undefined while the second test says that this.props.dispatch is defined.

The important point is that if I had used the default export of InnerConnect (Referred to as InnerConnectConnected in the code above) and had NOT used <Provider> to supply a store then the test would have failed with the error:

Invariant Violation: Could not find “store” in either the context or props of “Connect(InnerConnect)”. Either wrap the root component in a <Provider>, or explicitly pass “store” as a prop to “Connect(InnerConnect)”.

Note: I could have used enzyme’s shallow render (there is an example of that inside ConnectedClasses.test.js), and that would of worked. However enzyme’s mount or render methods gives a more useful output in this case. I tend to use mount, but that is just a minor preference on my part.

b: Nested components

ReactKanbanNestedComponentsOK, that was pretty straightforward, but life in a real application is never as simple as that. React components are designed to be nested. In the Kanban applications, taken from the excellent book “Pro React”, uses a set of nested components to show multiple lists of multiple card, where each card may have multiple tasks (called CheckList in the diagram).

This is pretty normal for a React.js application. Also, if you use Redux then many of the React components will need to access Redux. Once this happens then things get more complicated.

Let us look at a second example React component called OuterConnect. The module is repeated in full below:

 
import React, {Component} from 'react';
import { connect } from 'react-redux';
import InnerConnect from './InnerConnect';

export class OuterConnect extends Component {
    render () { return 
       <div>
          <h1>
             Outer.dispatch {
                 this.props.dispatch === undefined 
                    ? 'undefined' : 'defined' }
          </h1>
          <InnerConnect />
       </div>
    }
}
export default connect()(OuterConnect)

You can see this is very similar to the InnerConnect, but it has one big difference – it has the InnerConnect component inside its render method – this is known as nesting. At this point the following happens:

  • Shallow render still works without the Redux <Provider> as long as you call the undecorated class, in this case InnerConnect.
  • Full Dom render will NOT work without the Redux <Provider>. This is because the nested class, i.e. InnerConnect, will fail because it uses the connect method which expects to find a Redux store.

As Full Dom rendering, i.e. enzyme’s mount method, often provides a more useful output then supplying the store via the Redux <Provider> class is the most sensible way to go.

Note: If you want a full list of all the test options then look at the test ConnectedClasses.test.js. The tests that fail are set to be skipped and have comments to say how they fail.

I have done a few tests on parts of the Kanban components. You can find them all in the directory Tests/components. I use a mixture of shallow and mount rendering.

Testing events when Redux is involved

React components need to respond to events, like clicking a button. If Redux isn’t involved then these events are normally handled by changing the this.state inside the component. However, once a Redux store, or any other sort of store pattern, is used the state is mainly (always?) handled by the store. This means that simulating an events is likely to trigger a Redux action.

You could provide a full implementation of the store and (I assume, because I haven’t tried it) that the action would ripple through and cause whatever change was expected in the html. However I personally use redux-mock-store so that I can decouple the actions. Here is a simple example taken from Card.test.js .

it('call close card event', () => {
const identity = function (el) { return el; };
    // Wrap in DnD test context
    const CardConnectedWithDnD = 
       wrapInTestContext(CardConnected);
    const mockStore = configureStore([]);
    const store = mockStore({});
    const card = createCard();
    const wrapper = mount(
        <Provider store={store}>
           <CardConnectedWithDnD 
               {...card} 
               connectDropTarget={identity}/>
        </Provider>);
    expect(store.getActions().length).toBe(0);
    wrapper.find('div .card__title').simulate('click')
    expect(store.getActions().length).toBe(1);
    expect(store.getActions()[0]).toEqual({ 
           payload: { cardId: 0 }, 
           type: 'toggle card details' });
});

As you can see simulating the click (line 16) causes an action to be called, which the redux-mock-store records. The test then checks that action has happened and has the right content.

Quick aside – other decorated components

While this article is mainly about components using Redux there are other types of components that use data passed down to them. The example I had to fix was the use of DragAndDrop but I expect there are others. These need a similar approach to how we handle Nested Redux usage. However the actual way you inject the data varies with the library you are using.

Do have a look at Card.test.js and List.test.js with the helper class WrapTestDnD.js .

Conclusion

I did have to think about the best approaches to testing nested React components that use Redux. Having built myself a useful set of example tests in the shape of the ConnectedClasses.test.js tests then I thought it was worth publishing a detailed run through of how things work.

I hope this helps others with their React.js developments. Please feel free to leave a comment if you have more information to add, or especially if you spot a error on my part.

Happy coding.

Adding mocking to React.js Unit Tests

I am continuing to build up my set of templates to improve the tools used to develop, test and build React.js front-ends (see original article introducing my ASP.NET React.js templates). In my first iteration I created a project to contain my Unit Tests, but it only had five very basic tests. In this article I describe how I beefed up the Unit Tests, especially around mocking out ES6 modules.

The aims of this article

  • Why I chose the JavaScript mocking approach called inject-loader.
  • A detailed summary of how to use inject-loader, as it wasn’t totally obvious to me.
  • A quick aside on mocking JavaScript Promises.
  • Links an open-source project which contains an example of Unit Testing with Mocks.

I’m going to assume you at least know what React is and what Unit Testing is and why Unit Testing is useful. If you don’t know React try these article links [1, 2, 3]. I would also really recommend the book “Pro React”, which helped me a lot. On Unit Testing  and mocking try this overview article.

Note: One word of warning:  React.js is still changing and articles and books get out of date. This article and open-source AspNetReactSamples on GitHub uses React version 15.0.2 (see package.json for full list).

Setting the scene

I described my Unit Test environment in the first article, but in summary I am using the Mocha test framework run by the Karma test runner (read section 3 of the original article for why I, and others, don’t use the suggested Jest test framework). The whole React.js build environment uses Babel and WebPack extensively.

I had recently converted one of my React web apps over to use Redux and I wanted to create some proper Unit Tests. The React.js application, called Kanban (comes originally from the book “Pro React” book), uses async accesses to the server to fetch and save the data. This was pretty fundamental to how Kanban works and I needed to intercept this if I was going to test certain parts of the code.

I could have used a specific library to intercept the “fetch”, but I also needed to mock some other parts so I wanted a generic way of replacing ES6 modules with some stub or test code – this is called mocking.

Down the rabbit hole (again!)

In the first article I said that when I researched setting up the build process it “felt like I had fallen down Alice in Wonderland’s rabbit hole!”. Well, it felt the same when I tried to find a method to mock ES6 modules (but thankfully not quite as deep as with Webpack!).

I found this stackoverflow question and answers, which mentioned a number of ways, like rewire/babel-plugin-rewire library,  proxyquire and inject-loader. I spent a frustrating day trying to get babel-plugin-rewire to work to no avail before I swapped to try inject-loader.

Thankfully I found an excellent article called ‘Mocking ES6 import for Tests‘ by James Tease. This looked like just the thing, especially as he gives an example which uses Redux.

True be told I was still a bit confused and couldn’t get inject-loader to work. I didn’t find the inject-loader Readme file totally enlightening as I thought I needed to link in the inject-loader into my karma/webpack files (you don’t – all you need to do is load inject-loader, which you do by adding “inject-loader”: “2.0.1” to your package.json and updating your packages).

Mocking example

In the end I created a really simple test of mocking to check I understood inject-loader. First I will list three small modules that I created for the test. You will see that the final module, called ‘OuterFunction’, imports and used the other two (you can find the actual files in this directory)

//file InnerFunction.js
export default function inner() {
    return 'Inner Function';
}
//file InnerValue.js
export default 42;
//file OuterFunction.js
import InnerFunction from './InnerFunction';
import InnerValue from './InnerValue';

export default function outer() {
    return {
        innerFuncValue: InnerFunction(),
        innerValue: InnerValue
    }
}

This is a very contrived example, but they really helped me understand how to use inject-loader. Here is a section of my mocha test called ‘TestMocking.test.js‘:

import expect from 'expect';

import OuterFunction from '../../localSrc/OuterFunction';
import innerMock from '../../mocksEtc/MockInnerFunction'

describe('Test Mocking example', function () {

    it('check normal operation works',
    () => {
        var result = OuterFunction();
        expect(result.innerFuncValue).toEqual('Inner Function');
        expect(result.innerValue).toEqual(42);
    });

    it('mock InnerFunction with local function',
    () => {
        const localFunc = () => { return 'local mock'};
        const inject = require('inject?./InnerFunction!../../localSrc/OuterFunction');
        const outerFunctionWithMock = inject({
                './InnerFunction': localFunc
            }).default;
        var result = outerFunctionWithMock();
        expect(result.innerFuncValue).toEqual('local mock');
        expect(result.innerValue).toEqual(42);
    });
    //... lots more tests

The key lines are 18 to 21 so let me take you through each part as this is where I got confused.

Line 18 – the require statement

In one of the emails with James Tease he said using inject-loader “look weird” if you are used to ES6 imports. You can see what he means when you look at line 18. It is odd to see a require statement in ES6 code, but that is how inject-loader works, i.e. it alters the module as you load it. The format of the require parameter string is important so let me go through it in detail, with bold used to show each part:

  1. inject?./InnerFunction!../../localSrc/OuterFunction’
    The start of the string makes the inject-loader take over the load of the module.
  2. ‘inject?./InnerFunction!../../localSrc/OuterFunction’
    This says which module inside the ‘OuterFunction’ that we want to replace. It starts with the question mark followed by the EXACT same string used in the import statement in ‘OuterFunction’. Note: this part is optional – you can leave it out if you plan to replace ALL of the imports (example later).
  3. ‘inject?./InnerFunction!../../localSrc/OuterFunction
    This says what module you want to load, in this case the ‘OuterFunction’ module. The string starts with an exclamation mark and then has the correct file reference to access the module from where the test is being run.

Be warned: if you get part three wrong then you will get an error, but if you get part 2 wrong then it just doesn’t work.

Lines 19 to 21 – mock out the module(s)

This is the part that replaces the imported module inside the module you are loading. In this example we are replacing the ‘InnerFunction’ module inside the ‘OuterFunction’ module. Again there a a few things to watch out for:

  • line 20. Replacing a module.
    The content of the string ‘./InnerFunction’ is again crucial. It must be the EXACT same string used in the import statement inside the module you are loading, in this case the ‘OuterFunction’ module. The part after the colon is the new content. You can give it a whole module, or in this case just a function as that is all the ‘InnerFunction’ contains.
    Note: Do have a look at James Tease’s example ‘Mocking ES6 import for Tests‘ as he sends over an object. My TestMocking example Unit Test shows different ways to replace a module.
  • Line 21. getting the right exports from the loaded module
    You have loaded a module using require. Because of this you need to know how to access the parts that this module exports. If its an ES6 module then there is a convention for that. In the case of the ‘OuterFunction’ module it exports just one function as its default: therefore I can access it by adding .default to the end of the statement.  James Tease gives an example of accessing a specific class in his article, Mocking ES6 import for Tests.

More examples

There are lots of different ways you can use inject-loader. I have copied the following section from the inject-loader Readme file, so you can see things all in one place.

// If no flags are provided when using the loader then
// all require statements will be wrapped in an injector
MyModuleInjector = require('inject!MyStore')
MyModule = MyModuleInjector({
  'lib/dispatcher': DispatcherMock,
  'events': EventsMock,
  'lib/handle_action': HandleActionMock
})

// It is also possible to only mock only explicit require
// statements via passing in their path as a flag
MyModuleInjector = require('inject?lib/dispatcher!MyStore')
// only 'lib/dispatcher' is wrapped in an injector
MyModule = MyModuleInjector({'lib/dispatcher': DispatcherMock})

// this also works for multiple flags and requires
MyModuleInjector = require('inject?lib/dispatcher&events!MyStore')
// only 'lib/dispatcher' and 'events' are wrapped in injectors
MyModule = MyModuleInjector({
  'lib/dispatcher': DispatcherMock,
  'events': EventsMock
})

// you can also explicitly exclude dependencies from being injected
MyModuleInjector = require('inject?-lib/dispatcher!MyStore')
// everything except 'lib/dispatcher' is wrapped in an injector
MyModule = MyModuleInjector({
  'events': EventsMock,
  'lib/handle_action': HandleActionMock
})

To reiterate, it is important to get the strings in the right format:

  • When referring to the module you want to replace then you must use the EXACT file reference used in the import inside the module you are loading. If you get this wrong it doesn’t error, but it just doesn’t work.
  • The file reference for the module you are loading should be the correct reference to reach the module from where your test is located in the file system. If you get this wrong then you get the normal “file not found” type error.

Also the format of the inject has to match what the calling module expects. For mocking out simple modules that use a default return then you can just inject something that matches that default, e.g. a function in the case of my ‘InnerFunction’ example. For mocking out more complex modules with multiple exports then its often easer to create a mock of the module.

Note: Have a look at my file  ‘TestMocking.test.js‘ which has some really simple examples. If you want to see an example of the mocking used for real Unit Testing then have a look at CardActionCreators.tests.js, which tests the ActionCreators for a card in the Kanban app.

Quick Aside – mocking Promises

My main aim was to test some of the code that accessed data on the server via the “fetch” library. The “fetch” command is async and uses JavaScript Promises. I looked at how to mock a promise and found these articles [1, 2]. I tried a few approaches that these two articles suggested, but it definitely wasn’t simple. As Jani Hartikainen says in his article,  “dealing with promises in unit tests is a hassle“.

In the end I looked at how Promises were used in the kanban application and found it only used the then(success, failure) function of the Promise. I therefore created a really simple MockPromise that just has a just the then function. You can see me using the MockPromise in the ReduxDispatcher.test.js and CardActionCreators.tests.js.

Conclusion

I am slowly improving the dev, test, build tools in my React samples. In this article I have improved my ability to Unit Test a larger amount of my code base by adding mocking. Finding the right way to do that was a bit of a struggle as the tools, e.g. Babel, Webpack etc. are changing so some articles you read are out of date.

I do like the inject-loader but its syntax is not obvious and there isn’t a lot of documentation on how to use it. Hopefully this article and the associated example code will help you to understand and use the inject-loader to make your Unit Test more effective. Please feel free to point out other mocking methods that have worked for you, preferably with some example code that I and others can look at.

Happy coding.

Using a Redux store in your React.js application

This article is about the benefits of using the Redux library in your React application, followed by a detailed description on how to use Redux. These descriptions use code snippets from a open-source sample application which contains a React application called Kanban inside a ASP.NET Core web application.

This article follows on from my initial article Templates for building React.js front-ends in ASP.NET Core and MVC5 where I describe a number of example web applications which show how to create and build React.js applications inside various ASP.NET web sites.

When I created the samples I used the Kanban React app from the excellent book “Pro React” in two of the samples which used a library called Flux to simplify the handling of states.  However, in my review of the Pro React book on Amazon I said that the only down side of the Pro React book was it used Flux instead of the newer Redux library to implement stores. The author saw my review and left a comment to say an alternative version of Chapter 6 using Redux was now available.

This made me think – how about I change the Kanban app in one of the samples to use Redux, using Cássio’s new chapter as a guide? Well, I have done just that and this article is all about how to use Redux in your React application.

UPDATE: It turns out Cássio has also upgraded the Kanban app to Redux – see the new branch chapter6-redux on the Pro React github site. While seeing that would have saved me doing my own refactor I would not have learnt as much as I did by doing the work myself. However it does give me another version I can look at to see if I could have done things better. I comment on this later.

The aims of this article

  • To explain why using Redux is useful in a React.js application.
  • Describe the architecture of a React.js application that uses Redux.
  • Provide a point-by-point description of the different parts of a Redux/React application. That makes the article very long, but hopefully more useful.
  • Provide links to an example Redux/React application on GitHub.

Supporting material

This article is backed up with a number of ASP.NET projects which I have made available as an open-source Visual Studio solution, AspNetReactSamples, on GitHub. This currently contains four projects, but two of particular interest:

While these examples are aimed at ASP.NET MVC all the React code will work in any system supporting Node.js. You can try all the React code using Visual Studio Code, which is a free tool that runs on multiple platforms.

In addition React/JavaScript samples are available from the code associated with “Pro React” book, including a version of the Kanban application that does not use a store, but the more basic hierarchical approach (see below for an explanation of the difference).

UPDATE: As I said earlier Cássio has added a chapter6-redux version. It is very interesting to compare our two implementations. I found one area where I think Cássio’s implementation is better (I point it out later), but on the whole I am happy that my solution is pretty similar, especially as Cássio is the expert in this area.

NOTE: All the code in this article and supporting material is using the React JSX coding style and the new ECMAScript 6 (ES6) JavaScript format. If you aren’t familiar with these styles (I wasn’t until a few months ago) then it will look strange to you at the start. I haven’t found any problems embracing either JSX or ES6 format, in fact I like it a lot, but if you haven’t seen it before it looks wrong.

Introduction to why Redux is useful

(Skip this section if you already know React)
I’m going to assume you at least know what React is. If you don’t then I recommend reading the article Thinking in React and maybe some of these articles [1, 2, 3]. I would also really recommend the book “Pro React”, which I think is excellent.

ReactKanban-hierarchical-viewReact is very hierarchical, with various components put together in a parent-child relationship to create the final UI component. In small applications you can pass data downwards using React this.props and return data changes back up the hierarchy via callback functions.  See diagram on the right of the Kanban app using this ‘chaining’ approach.

In small React applications then using a ‘chaining’ approach is fine. However when you are building something bigger then this approach starts to cause problems. These problems have resulted in the development of what are generically known as a ‘store’ to handle the changing data. The benefits of using a store over a ‘chaining’ approach are:

  1. In the ‘chaining’ approach the data access and business logic is spread throughout the various React components. As you will see later a store takes data access and business logic code out of the components and into separate modules. This leaves the React parts handling just the UI and lets another part of the application handle the changing data. This makes for a much better separation of concerns and hence the application is easier to understand and refactor.
  2. When using a ‘chaining’ approach then each level in the hierarchy passes the callbacks down to the next lower levels. This makes refactoring React components difficult because they are inextricably linked through these chains. See this version of the Kanban application that does not use a store and note the passing of callbacks in most of the components.

In a store based implementation the ‘store’ takes over the handling of data that can change. All the react components then link to the store to a) to trigger an action on an event and b) to get updated if something changes.

There are many versions of these stores: Flux was one of the first, but the Redux library has shown to be a good alternative. In my opinion Redux is exceptionally good at separation of concerns, with a clear break between the Store that holds the data, the code that changes the store (Reducers) and the Actions that the components call to ask for a change.

The flow of control in the Kanban app using Redux is shown below, with the various steps numbered 1, 2, 3:

ReactKanban-redux-view

The text below describes each step using two words that Redux uses, Action and Reducer, which I explain in more detail later.

  1. Action: When an event happens inside a React component it now calls an Action, via a Redux function called dispatch. An action returns an object which always contains an action type.
  2. Reduce: Redux calls all the reducers which then use the action type to decide which reducer method should be run. The reducer’s job is to updates the Redux store for this action type, using any extra data that the action may have included.
  3. Update: Because the store has changed Redux calls a specific function in any component that registered with it. This function allows part/all of the new store values to be copied into the component’s props. Changing the props automatically causes the component to call its render function.

Details on the parts of a Redux solution

In this long section I will go detail each of the parts you need to add/change in your React application to use Redux. I will link to the actual code example application I refactored, which means you can try out the final applictaion.

1. The Redux Store

The simplest part about Redux is the store itself. Its job is to hold the data and it has a small list of API commands that make things happen. In this case we will use two commands to setup and create the store. Below is the total content of the file store/reduxStore.js which creates the single store:

import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import throttle from 'redux-throttle';
import reducers from '../reducers/index';

const defaultThrottleOption = { // https://lodash.com/docs#throttle
  leading: true,
  trailing: false
}
const throttleMiddleWare = throttle(500, defaultThrottleOption);
const reduxStore = createStore(
   reducers,
   applyMiddleware(thunk, throttleMiddleWare) 
);

export default reduxStore;

The Redux store is designed that you create just ONE store, and the code above is my code to do that. Because Kanban, like most sensible apps, uses async API accesses then we need the slightly more complex setup using the Redux applyMiddleware feature. This allows us to add special handling for certain features such as async functions. The two features I add are:

  • The ‘redux-thunk’ library, which provides async handling (described later)
  • The ‘redux-throttle’ library, which provides a debounce or throttle feature which I need for some of the functions that get fired while a drag-and-drop move is under way.

2. Actions

Actions are what your various React components call, via Redux’s dispatch function, to get anything done. Some of your actions may request data, e.g. fetchCards(), and some may do some more business-like logic, e.g. updateCardStatus(cardId, listId). The point is that all data access or business logic is placed in the action rather than in the React component where the event happened. That way the React components can focus on the display of the data and the actions can focus on the logic to change the data.

Note: The removal of this.state from a React component allows you to use a simpler form of React component called a “stateless functions“. Well worth looking at for simple react components, like buttons, or setting styles etc. This article has some more information on stateless functional components.

In any reasonable sized applications you will have multiple action files. In Kanban there are two: actions/CardActionCreators.js and actions/TaskActionCreators.js. In the Kanban app’s case the split is fairly arbitrary, and I think the CardActionCreators.js file could be split further.

Now down to the detail. In all cases an action will, eventually, return an object with at least a type variable, which contains a unique type. The simplest form is just that – a function returning a JavaScript object. Here is an example:

  toggleCardDetails(cardId) {
    return {
      type: constants.TOGGLE_CARD_DETAILS,
      payload: {cardId}
    };
  }

Note: As you can see in the example above, the type is taken from the object constants. The norm is to create file which holds all the action types and always refer to type via this. This makes sure you don’t make a mistake when typing an action type in different places in the application.

The second form is a function that returns another function of a specific signature. To use this form you need the store to include redux-thunk middleware you saw in section 1. This function form can be used in two cases:

a. Handling actions that use async functions

An async function is a function that kicks off a task and returns immediately before the task has finished, e.g. a request for data from an external source. Once the task finishes it will return a new result that Redux needs to pick up.

To handle this async case your initial action needs to return a function, not an object. Here is an example which uses Kanban’s dispatchAsync function to call dispatch with the correct success/failure when the async task ends:

  fetchCards() {
    return (dispatch) => {
      dispatchAsync(KanbanAPI.fetchCards(), dispatch, {
        request: constants.FETCH_CARDS,
        success: constants.FETCH_CARDS_SUCCESS,
        failure: constants.FETCH_CARDS_ERROR
      });
    }
  },

b. When the returned object needs to be calculated

If you need to execute some JavaScript code before you return a result then you need to use the function return format. The action below needs to extract the card id and status before it can persist the card’s change in status. Notice the second parameter, getState, which gives you access to the store’s content.

  //Warning: This type of usage does not support server-side rendering.
  //see this SO answer for more on this http://stackoverflow.com/a/35674575/1434764 
  persistCardDrag(cardProps) {
    return (dispatch, getState) => {
      let card = getCard(getState().cards, cardProps.id)
      let cardIndex = getCardIndex(getState().cards, cardProps.id)
      dispatchAsync(KanbanAPI.persistCardDrag(card.id, card.status, cardIndex), dispatch, {
        request: constants.PERSIST_CARD_DRAG,
        success: constants.PERSIST_CARD_DRAG_SUCCESS,
        failure: constants.PERSIST_CARD_DRAG_ERROR
      }, {cardProps});
    }
  },

NOTE: the comment at the top of this code that points out that this technique for accessing the store does not work when doing server-side rendering. Because this application is not using server-side rendering this approach is OK here. However please read this SO answer for more on this subject.

3. Reducers

Redux defines a very specific approach to how the store is changed. It does it through what it calls ‘reducers’. A reducer is a function that take the current state of the store and a specific action object and produce a new, immutable (unique) store content. I think of reducers as using a repository pattern, i.e. some code that turns a client centric command, e.g. updateCardStatus(cardId, listId), into some sort of change to the data in the store.

The reducers are only called by the Redux store, i.e. you don’t call them yourself. It is the action type provided by the Action that defines which reducer method is called to alter the store. There are often multiple reducers, with different reducers looking after different bits of the stored data. In my case I have a reducers/cardReducer.js and a reducers/draftCardReducer.js. Redux calls all the reducers and lets them decide what should be run.

The normal pattern for a reducer is to use switch statement using the type variable in the action object (see code below) to select the right method to run. While you could use other approaches using a switch does make it obvious what is happening when looking at the code. Here is the start of my cardReducer.js:

import constants from '../constants';
import { getCardIndex } from '../cardUtils'
import update from 'react-addons-update';

const initialState = [];

const cards = (state = initialState, action) => {
    switch (action.type) {
      case constants.FETCH_CARDS_SUCCESS:
        return action.payload.response;
      /*
       * Card Creation
       */
      case constants.CREATE_CARD:
        return update(state, {$push: [action.payload.card] })

      case constants.CREATE_CARD_SUCCESS:
        cardIndex = getCardIndex(state, action.payload.card.id);
        return update(state, {
          [cardIndex]: {
            id: { $set: action.payload.response.id }
          }
        });
           //... lots more case statements
      default:
        return state;
    }
}

export default cards;

A few things to note:

  • The function is called at the start with no parameters. This results in the state being set to the initialState, in this case an empty array, and because the action will be undefined the default path will return that state.
  • In each place where we change the store we use the update command from the ‘react-addons-update’ library. This does an immutable update, i.e. it creates a brand new object while leaving the old state as it was. That is very important to Redux, but I don’t have the space to go into why – read this for some reasons why Redux does this.
  • The name of the function, in this case cards, is important as it the name that is given to the part of the store that this reducer looks after. That means that the command getState().cards will return the data that this cardReducer deals with.

4. Making the store available

Because Redux has only one store we need to make it available to any component that needs to call an Action or be updated if the store changes. The first step is to get the store known to React at the top level. For that we use the ‘react-redux’ class Provider which apply as an outer class on our app’s main  entry point. Here is link to my App.js which also uses a router etc, but below is simple example make it more obvious what is going on:

let store = createStore(myReducers)

render(
  <Provider store={store}>
    <YourApp />
  </Provider>,
  document.getElementById('root')
)

5. Accessing the store in React components

5.a The standard approach

Having used the Provider class at the top level we can access the store using Redux’s connect function. I will give an example of how I set up the use of Redux in my KanbanBoardContainer.js file with some code snippets. The most-used approach is to supply two functions to the connect function:

  1. mapStoreToProps: this is called when the store changes and copies the part of the store that it needs into a local prop, or multiple props. In this case we read all the cards into the prop.cards.
  2. mapDispatchToProps: this allows you to set up functions that will call the actions you need, but linking them into Redux via Redux’s dispatch In this case the class only needs the fetchCards function, and that gets mapped to this.props.fetchCards inside your React component.

Note: Redux calls the first function mapStateToProps, rather than my mapStoreToProps. I changed the name as ‘state’ has a specific meaning in React and the name ’mapStateToProps’ really confused me at the start, as I thought it was referring to React’s this.state… .

Below is the end of the components/NewCard.js file from the Kabban app. You can see the two functions and how they are used to a) subscribe to Redux’s update if the store changes and b) make some actions available inside the component.

//... the start of the class has been left out
function mapStoreToProps(storeState) {
  return {
    draft: storeState.draftCard
  }
}

function mapDispatchToProps(dispatch) {
  return {
    updateDraft: (field, value) => 
        dispatch(CardActionCreators.updateDraft(field, value)),
    addCard: (card) => 
        dispatch(CardActionCreators.addCard(card)),
    createDraft: (card) => 
        dispatch(CardActionCreators.createDraft(card)),
  }
}

export default connect(mapStoreToProps, mapDispatchToProps)(NewCard)

Once you have done this an action can be called via the props, e.g. this.props.addCard(this.props.draft). Also, if the Redux store is changed then mapStoreToProps is called and, in this case, updates the props.draft variable, which in turn causes React to run the render method inside this component.

Tip: Quicker linking to actions

A variation of the mapDispatchToProps is to use Redux’s bindActionCreators function. This is a quick shorthand that binds all the actions in an action creator to this.props.actions.<youraction>. You can see an example in the components/CheckList.js.

I used the bindActionCreators function in CheckList because the react component called all of the actions defined in TaskActionCreator, so it was easier to use the bindActionCreators function. I tend to hand code when I use a subgroup of the actions so that I’m not linking to an action I don’t use. Maybe I’m being too picky – just using Redux’s bindActionCreators function is certainly easier. You can decide what you want to do.

5.b The minimal approach to calling an action

Sometimes you only want to access say one action, and going through all the mapping seems overkill. In this case you can use the react-redux’s connect function, but without any parameters. In this case the Redux function dispatch is added as this.props.dispatch and you can call a action using it, e.g.

this.props.dispatch(
   CardActionCreators.updateCardStatus(dragged.id, props.id))

I do this in the components/List.js component.

5.b The minimal approach to accessing the store

It is possible (but highly unlikely – it is not good practice) that you want to access the store directly. You can use something called the React context which, if you click the React context link, you will see it has a ‘use with care’ notice on it, so be warned.

However the react-redux Provider class we used to make the store available throughout the application places link to the store in this.context.store. You can access it in any React component by adding the following code to YourClass (very similar to propTypes, but for React context)

<YourClass>.contextTypes = {
  store: React.PropTypes.object
}

I thought I needed to do this in component/EditCard.js and implemented the use of context. Now I know more I might have used the normal mapStoreToProps, but I left the EditCard code as it always good to have an example of using the context to refer back to.

Update: Cássio’s EditCard.s implementation is, in my opinion, much better. He uses mapStoreToProps approach with access to ownprops. Here is his code in the EditCard.js file:

const mapStateToProps = (state, ownProps) => (
  {
    draft: state.cardDraft,
    card: getCard(state, ownProps.params.card_id)
  }
);

Unit Testing

As I said at the start I think Redux does a great job of separating each of the parts of the problem into separate areas. In addition the Actions and Reducers are completely self-contained and know nothing about the Redux store. As the Actions and Reducers contain some of the key code then this makes Unit Testing much easier.

Rather than make this article even longer I refer you to Redux’s useful Writing Tests section.

UPDATE: I have started to extend the Unit Tests in the sample application, especially around testing the Redux version. You can read about how I mock out modules in the new article Adding mocking to React.js Unit Tests and see my current React Unit Tests in the ReactWebPack.Core project under the JsUnitTests directory.

Conclusion

Firstly, well done for getting this far, as it is a long article.

Like every new technology I approach Redux was a struggle to understand at the start, but once I began writing some code, finding it didn’t work and fixing it then it began to come together. GitHub tells me it was only four days, but it seemed longer as there were a number of new approaches I hadn’t seen before. Hopefully this article, which was partly written as I was doing the upgrade, will help you on your own journey with Redux.

From my experience of using Redux I think it is a very nice tool. I especially like its very clear separation of each different aspect: store, actions and reducers. That means I only have to think about one problem space when I am working in each part – which frees me to be much more focused and productive.

I hope this has been helpful. If you spot anything I misunderstood (I am still learning!) then do let me know.

UPDATE: I have written another new article called Adding mocking to React.js Unit Tests which adds a new capability to my Unit Testing tools. This is especially relevant to the Redux version of the Kanban application as some of the tests I have created are aimed at testing the action parts of the Redux system.

Happy coding!

 

Templates for building React.js front-ends in ASP.NET Core and MVC5

I have been interested in React, Facebook’s libraries for building front-end User Interface, for some time. Having worked on a Single Page Application (SPA) some years ago that used Backbone I was very aware of the pain point React is aimed at, i.e. the problem of building and debugging complex views with lots of interactions (see Why React?).

Recently I got some spare time and I decided to create some samples ASP.NET MVC applications that used React so that I was clear on how I could use it in the future. Well, it turned out WAY more complex than I thought but I learnt a lot!

This article is the first article in the series I am writing about creating a React.js samples that are a good starting point for real-world, production-ready applications with full React.js build, test, and deploy capabilities. The other articles in the series are:

  1. This article: Templates for building React.js front-ends in ASP.NET Core and MVC5
  2. Using a Redux store in your React.js application
  3. Adding mocking to React.js Unit Tests
  4. This article: Unit Testing React components that use Redux

Note: While my solution is aimed at ASP.NET MVC all React code and build/test files would work in any system supporting Node.js. You can try all the code using Visual Studio Code, which is a free tool that runs on multiple platforms.

What this article is all about

My aim was to produce sample applications that I could use as a basis for building real-world ASP.NET MVC applications that used React to help build the UI. As such they needed to have:

  1. Good development environment.
  2. Good Unit Test setup.
  3. Good production building setup.
  4. Examples in both flavours of ASP.NET, e.g. the existing MVC5 and the new ASP.NET Core MVC.

I ended up making a number of projects which I have made available as an open-source Visual Studio solution, AspNetReactSamples, on GitHub. This currently contains four projects:

  • ReactJsNet.MVC5, which uses the ReactJS.Net NuGet package.
  • ReactWebPack.Core, which used WebPack and the new ASP.NET Core (version 1.0.0) MVC app. This project also contains a set of JavaScript Unit Tests. (NOTE: This projects started out at CORE version RC2 but I have updated the project to CORE 1.0.0 now. The URLs still say CoreRC2 as it was difficult to chaneg them, but it is really Core 1.0.0.)
  • ReactWebPack.MVC5,  which used WebPack and the existing ASP.NET MVC5 app.

The bulk of this article goes though the decisions I made when putting these examples together. Having ‘cut-and-pasted’ other people’s examples and got lost, I think knowing why I built something that way is as important as knowing how.

I’m going to assume you at least know what React is and that it has lots of associated libraries. If you don’t then there are plenty of articles out there on React [1, 2, 3] but I would also really recommend the book “Pro React”, which helped me a lot.

NOTE: In my review of the book on Amazon I said that the only down side of the Pro React book was it used Flux instead of the newer Redux library to implement stores. Well the author, Cássio de Sousa Antonio, saw my review and has made available an alternative version of Chapter 6 using Redux. How about that for good service!

UPDATE: I have recently taken Cássio’s new chapter on using Redux to heart and converted the ReactWebPack.Core project over to using Redux. You can read about why Redux is really useful and how to use it in my article Using a Redux store in your React.js application.

OK, let’s start with the first example of how to use React in an ASP.NET application. This is the simplest to use, so makes a good starting point for anyone looking at React for the first time.

1. For simple applications try ReactJS.Net

If you want a simple place to start with React on ASP.NET then try the ReactJS.Net NuGet package from Facebook. This allows you to write JSX code which it turns into JavaScript on the fly. I have an example in my sample application called ReactJsNet.MVC5. (React.Net is also available for ASP.NET core RC1, but with a few limitations. See Nuget package ReactJS.NET MVC6).

Note: JSX is a source format that combines html and JavaScript. Sounds horrible, but it works, although you can write regular JavaScript if you prefer. Read this for an opinion on why it’s better to use JSX. More on the impact of using JSX later, but here is an example of some JSX.

var Comment = React.createClass({
    rawMarkup: function() {
        var rawMarkup = marked(
            this.props.children.toString(), {sanitize: true});
        return { __html: rawMarkup };
    },
    render: function() {
        return (
          <div className="comment">
            <h2 className="commentAuthor">
              {this.props.author}
            </h2>
            <span dangerouslySetInnerHTML={this.rawMarkup()} />
          </div>
      );
    }
});

If this React class Comment was called with the following JXS code:

<Comment author={'Jon Smith'}>
   {'This is a **bold** comment'}
</Comment> 

then the rendered HTML would be as shown below. Note that the method ‘marked’ is a library call that turns markdown into HTML, so “**bold**” gets turned into “<strong>bold</strong>”

<div class="comment">
  <h2 class="commentAuthor">Jon Smith</h2><span>
      This is a <strong>bold</strong> comment
   </span>
</div>

My verdict on ReactJS.Net

ReactJS.Net makes starting using React really easy, but by default it uses the simple module linking of each library, i.e. using a global variable that other packages use, for example the way we often use JQuery in ASP.NET. In any substantial front-end system this style of module linking has its limits, and that is especially true with React as there are lots of libraries to include.

Therefore ReactJS.Net is a great solution if you want to add some simple React views to an existing ASP.NET project, or you just want to play with React. In my samples the ReactJsNet.MVC5 project implements the React Quick Start Tutorial of a simple chat.

However for bigger applications, or applications that needs more React features such as stores and routing, we need to handle the finding and linking of JavaScript module and libraries in a better way.

Note: You can use a system of linking modules on top of using ReactJS.Net, but then you need to use the more complex build process I describe in the next section.

However before we leave ReactJS.Net there is one feature that is very important – that of server-side rendering of React. This is really important as you can pre-render some React on the server and then tell the client-side React that the html has been pre-initialised and it will work with it. These sorts of application are called “Isomorphic Apps” (not a very helpful name in my opinion) but I don’t have the space to cover this. Have a look at these articles [1, 2, 3] and chapter 8 of the “Pro React” book I recommended to find out more about “Isomorphic Apps”.

2. Building React applications with JavaScript modules

For larger, more complex React applications then you are going to have lots of separate files (React components are normally small) and lots of libraries that you want to link to. Linking by loading them in sequence is not a viable option. So you need two things: a) a package manager to get the libraries and b) a way to link your code and the libraries together.

2.a. Library package manager

In the JavaScript world there are a number of package managers, the biggest two being NPM and Bower. While I am a fan of Bower it soon became very clear that React uses NPM extensively.  In the end it was obvious I needed to use ASP.NET’s package.json file and NPM, as using Bower would not have given me the access to all the libraries I needed.

2.b. Linking code and libraries.

This one was more complicated and it felt like I had fallen down Alice in Wonderland’s rabbit hole! The build of a normal React goes like this:

  1. Transpile the JSX: Because I have chosen to use the JSX format then I need this translated that format into ordinary JavaScript (ES5). This needs a Transpiler. I used Babel, which is well respected, but there are others, like Traceur from Google.
  2. Extract ES6 Modules: Because I am using the Babel Transpiler it understands the new ES6 module format which everyone in the React camp seems to use. Babel currently converts ES6 modules to a number of formats such as Common.js, AMD/Require etc. (Note: the ES6 module feature is at the time of writing not supported by any browsers natively, but is coming soon to Microsoft Edge).
  3. Load and link the references: React libraries have lots of links to other libraries and it would be a real pain to have to hand-locate each library. There are a few ways to do this, but WebPack seems to be the way that most React developers use. There are a number of alternatives to WebPack.

Other Benefits of this process – ES6 JavaScript

If you are using a Transpiler then it makes sense to make the most of it. What most people do is swap over to using the new ES6 JavaScript standard which has a number of very useful enhancements. You have already heard about modules, but there are things like let and const and classes. Also many of the functions I used from the JavaScript underscore / lodash libraries like _.map() are built into ES6. The benefits are cleaner, more rigorous code and you are somewhat future-proofing your code. Have a look at “Top 10 ES6 Features every busy JavaScript Developer must know”.

Babel converts all the ES6 commands to regular JavaScript (ES5), plus has a babel-polyfill library so that the code will run on all the modern browsers. Babel can output code for older (ES3) browsers but you need to add some more settings and libraries (see this useful note about that).

The down side of this process – JavaScript ‘build’

The down side is that you have to ‘build’ the JavaScript, even in development mode. For anyone used to using JavaScript with ASP.NET MVC you know that it’s great to be able to debug JavaScript by simply editing the JavaScript, hit F5 in the browser and you are away. Now you need to run the build process on every change.

However there is one saving grace. WebPack has a “watch” mode and if you start this it will rebuild when you save a JavaScript/JSX file. A normal build takes some time, 6 seconds for my simple sample, but because WebPack caches the build then changing a single file normally takes ½ second.

2a. Setting up a build process

I would say that setting up the build process was the hardest and most frustrating part of the project. There are lots of different ways to set it up, each with its own pros/cons. The main problem, especially with WebPack is if it didn’t work it was really hard to find out why. Let me tell you some of the decisions I made so you know where I am coming from:

Big decisions

  • I used Babel for my Transpiler. That is what everybody is using and it worked well.
  • I used WebPack for my module bundler because everybody else seem to use it. I found WebPack really hard work to configure but it works now. I have since heard about systemJs and jspm, which follow the ES6 module approach. I am definitely going to look into those!
  • I chose WebPack as the command to call to build as it has a ‘watch’ facility to recompile on changes to a file. I think that is best, but you can call Babel, which then calls WebPack.
  • I chose to write NPM “scripts” to call WebPack. These scripts live in the package.json file. I quite like this, and it works for Unit Testing too (see later).
  • I chose to use the NPM Task Runner extension to call these scripts in Visual Studio, and the VSCode npm Scripts extension to run them in Visual Studio Code (more on that later). I tried other approaches such as the WebPack Task Runner, but NPM definitely worked the best.

Small decisions

  • I chose to use the extension ‘.js’ for my JSX code rather than ‘.jsx’. A lot of people do that and the tools handle either. Not much in it, but if you use .jsx then when you use the module import you have to add ‘.jsx’ on the end of the filename. (note: the build files in the sample applications are set to ONLY look at .js files).
  • This is a bit deep so ignore until you understand WebPack, but I didn’t use WebPack’s dev server to deliver the bundles files in the development build. This was partly because I had problems with setting up sourcemaps but I also liked having the Bundled JavaScript file around to look at. However I did use WebPack’s dev server in the Unit Testing, for no better reason than it worked that way by default.

To see other people’s approaches to the React build process, some of which I learnt from myself,  especially the first one, then do look at:

2b. How to run the build process

The best way to study my build process is to download the AspNetReactSamples and run a build. There are two versions which build and run the same React application, but for the two current version of ASP.NET MVC:

  1. ReactWebPack.Core, which is built on the new ASP.NET Core MVC app.
  2. ReactWebPack.MVC5, which is built on the existing ASP.NET MVC5 app.

The full information on how to do this is in the Readme.md file in the AspNetReactSamples solution so I won’t repeat it here.

Note: One nice trick is to use Visual Studio Code (VSCode) alongside Visual Studio (VS2015). If you aren’t aware of VSCode it’s a free, lightweight IDE which is especially good with JavaScript etc. In fact I found that VSCode understand JSX format better that Visual Studio 2015. In fact I find myself developing with both VS2015 and VSCode open: VS2015 for the C#/ASP.NET parts and VSCode for the React parts. There are details in the Readme file on how to set up the build environment in both VS2015 and VSCode.

3. Unit Testing

One of the plus points of React is that it is easy to Unit Test for two reasons. Firstly it is easier because React uses what is called a ‘Virtual Dom’, which is an in-memory DOM. The Virtual Dom means that the Unit Tests tools can check the virtual Dom rather than the actual DOM, which can be slow and troublesome. The second reason is that Facebook, and other React library suppliers like Redux, have thought about Unit Testing from the start and made sure their components/libraries are easy to test.

Even so, setting up a sensible Unit Testing environment still took quite a bit of research and trials. Let me tell share with you the choices and decisions I made so you can understand why I went this way:

Big decisions

  • I chose Mocha as my test framework. Facebook recommend Jest for Unit Testing React, but a number of posts [1, 2, 3] said Jest was slow and Mocha was better. I have also used Mocha successfully in the past, which gave me confidence in this approach.
  • I used Karma as my test runner. Most people do and I have used it before. Specifically it has a ‘watch’ facility and can interface with WebPack, which means it does a recompile and test when a test file is changed. That feature makes a big difference to the test/fix cycle.
  • I run my Unit Tests inside a real browser, Chrome, rather than a phantom browser. This adds a bit of start-up time but it does mean I can debug my Unit Tests (I talk about that later).
  • I used AirBnB’s Enzyme React testing utility. I had lots of trouble with my early tests, mainly because The “Pro React” book I mentioned used a very old version of React, and things had change. However even when I was looking at the correct code was still quite complex, with extra libraries and different approaches for handling render to the DOM. The React Test Utilities page suggested Enzyme which found much simpler to understand and use than the standard React Test Utilities. Enzyme also handles the render/DOM issue that was bugging me when using the standard React testing approach.
  • I used mJackson’s expect assertions rather than the older expect.js library I used before. mJackson’s expect has shorter test names and has its own event spy part. The spy part is significant because I saw lots of questions/problems about getting Sinon, the normal package for doing spying on events, working with with WebPack.
  • I placed my Unit Tests in another Visual Studio project, mainly because I want to keep my test code separate. UPDATE: It turns out that placing the Unit Tests in another project was a bad idea. The problem is you get the ‘multiple copies of React‘ error in some cases. I therefore have moved the JavaScript Unit Tests into the ReactWebPack.Core project (I have updated all the links)
  • I added NPM scripts in the ReactWebPack.Core’s package.json file so that the tests could be run in same way as the build. That way I can call them for Visual Studio or VSCode. I tried other ways but this was certainly the best.

I have only done a limited amount of Unit Tests (only 5 Unit Tests at the moment) UPDATE: I done a lot more work on Unit Testing around Mocking – read my new articles Adding mocking to React.js Unit Tests and Unit Testing React components that use Redux. Only a real application will tell me whether I have the right setup (my Backbone SPA had over 700 Unit Tests), but I am becoming more confident on the Unit Test setup.

 

In addition there is stacks of information on Unit Testing React because lot of people, like Facebook and Airbnb, use Unit Tests. Try:

3b. Running the React Unit Tests

Again, if you want to look at the Unit Tests, I recommend you download the AspNetReactSamples solution and look at the ReactWebPack.Core project. There are two files in the top directory, karam.config.js and tests.webpack.js, which control the Unit Tests, with certain libraries added to the package.json file. The actual Unit Test code is in the directory JsUnitTests directory. The Readme.md file in the AspNetReactSamples solution has all the information for running the Unit Tests, so I won’t repeat that. However here are some thoughts on Unit Testing React.

Debugging with Unit Tests

You can run the Unit Tests once by calling the command test-run. It will tell you what passed or failed. However when you do have a failing bug it is very useful to be able to debug it by inspecting the code and live variables, change the code and retest. Therefore I have added a test-watch that a) runs the tests, but leaves the browser open and b) will rebundle and rerun the tests if a .js file is changed.

Because the test-watch command leaves the browser open then you can use Developer Mode (F12) to place breakpoints in the code and rerun the tests by pressing F5 in the browser. Then you can inspect the code and the live variables to see where the problem is.

However because we are working with JSX and a Transpiler there is a wrinkle!

The issue of transpiled code

By default Chrome will find the source maps and show you the original JavaScript/JSX file. This is really helpful, but can be misleading as you aren’t looking at the actual code that is running. Mostly it’s fine, but imported methods/variables will have different names in the Chrome ‘scope’ window from what you see in your original code.

If you want to see the underlying ES5 code then the only way I have found to do that is to turn off ‘Enable JavaScript source maps’ in Chrome’s developer setting and press F5 again. Then you see the real code, which shows the correct variable names.

Once you get used to it it’s fine, but I got very confused at the start.

Note: Mocha has some useful commands when you are working on a large set of tests. The most important is the .only() method which, if added to a test/sub test, will only run that test. Also the .skip() method can be added to a test/sub test and causes it to be skipped.

Another useful feature is adding the line debugger; to your JavaScript which will cause a breakpoint when it is executed if the developer tools (F12) is open.

Conclusion

I started this project by cut-and-pasting solutions I found on the web and got terribly lost, especially because some things like WebPack can ‘fail silently’, e.g. does not do what I wanted it to do, but did not produce any error messages. Therefore when I wrote this article I took the time to include the decisions I made and why. I hope that helps you to decide what you want to do, and more importantly help you understand what is wrong when it doesn’t work.

This has been quite a long research project for me, but at the end I have what I consider a really good example setup that I could use in a real project. My final solution ticks almost all the points I needed apart from having multiple React apps (but I know how to do that).

My journey with React had only just begun and there is much more to learn. If I have time I plan to look at systemJs and jspm as an alternative to WebPack (have a look at this video on HTTP/2 and systemJs to see why this looks like a good way to go).

UPDATE: My journey with React continues. I have written a new article called ‘Using a Redux store in your React.js application’ which explains the advantages of using a store like Redux and then detail the steps needed to switch your React application over to using Redux. The application ReactWebPack.Core in the samples has been altered to use Redux so you can see it in action.

UPDATE: Another new article called Adding mocking to React.js Unit Tests which adds a new capability to my Unit Testing tools.

Happy coding!