Tutorial

Testing React / Redux Apps with Jest & Enzyme - Part 3: Testing Redux Actions

Published on June 27, 2018
author

Jasper Valero

Testing React / Redux Apps with Jest & Enzyme - Part 3: Testing Redux Actions

This is part 3 of a 4-part series on testing React / Redux apps using both Jest and Enzyme for a robust testing solution. In this part we’ll cover some simple examples on how to test Redux actions.

The series

We’ll now be moving into testing on the Redux side of things. This is where you begin to test business logic and application state. A benefit of using Redux in your applications is easy separation of business logic from rendering. You can write Redux tests that focus on the latter.

So let’s jump in and start writing some tests for our Redux actions.

Mock out your Redux Store

Thanks to the redux-mock-store npm package that we installed we can mock our store in just two lines of code.

__tests__/actions/select_actions.test.js
import configureStore from 'redux-mock-store';

// Actions to be tested
import * as selectActions from '../../actions/select_actions';

const mockStore = configureStore();
const store = mockStore();

// ...

After mocking our store we gain access to some very nice test helpers such as dispatch(), getActions() and clearActions() which we’ll be putting to use next. For a full list of available methods you can check out the redux-mock-store API documentation.

  • The dispatch() method dispatches an action through the mock store. The action will be stored in an array inside the instance and executed.
  • The getActions() method returns the actions of the mock store.
  • The clearActions() method clears the stored actions. Great for setup and teardown.

Keep your Mock Store Sterile

With unit testing a lot of tests get ran in succession. To ensure we’re not getting results from a previous test we’ll write a small amount of setup code to clear out all actions from our mock store before running each test. We’ll leverage clearActions() for this.

__tests__/actions/select_actions.test.js
// ...

describe('select_actions', () => {
  beforeEach(() => { // Runs before each test in the suite
    store.clearActions();
  });

  // ...

});

Test your Actions

In order for our Redux state to be updated properly we have to be sure that the correct actions and payloads are dispatched into our reducers. In our tests we’ll dispatch actions into our mock store using dispatch(). We’ll then check that the correct action type and payload are returned using getActions().

So let’s go inside of our select_actions test suite and add some action tests.

__tests__/actions/select_actions.test.js
// ...

describe('selectAvatar', () => {
  test('Dispatches the correct action and payload', () => {
    const expectedActions = [
      {
        'payload': 1,
        'type': 'select_avatar',
      },
    ];

    store.dispatch(selectActions.selectAvatar(1));
    expect(store.getActions()).toEqual(expectedActions);
  });
});

// ...

Once you have your test passing you can take advantage of Snapshot testing from Jest. This has the added benefit of letting you reduce your test code. Here’s an example:

__tests__/actions/select_actions.test.js
// ...

describe('selectAvatar', () => {
  test('Dispatches the correct action and payload', () => {
    store.dispatch(selectActions.selectAvatar(1));
    expect(store.getActions()).toMatchSnapshot();
  });
});

// ...

If you recall from the Testing Smart Components section of Part 2 I recommended testing your actions separately from your components. If you look at the expect() assertion in the code example in that section you’ll see some familiar code. This goes to show that you can keep things isolated without losing test coverage.

Bonus Tip!

You can get into writing some very advanced action tests. I’d like to offer that with actions, less is more. If you find yourself writing a lot of complex tests you may need to rethink your Redux architecture. Things should feel light and easy when it comes to managing, thinking through and testing your Redux actions. Especially with this setup. Food for thought!

What’s Next?

In Part 1 of this series I showed you how to install and setup Jest and Enzyme. In Part 2 I covered testing React components. We’ll finish up in Part 4 with testing Redux reducers. Stay tuned!

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Learn more about our products

About the authors
Default avatar
Jasper Valero

author

While we believe that this content benefits our community, we have not yet thoroughly reviewed it. If you have any suggestions for improvements, please let us know by clicking the “report an issue“ button at the bottom of the tutorial.

Still looking for an answer?

Ask a questionSearch for more help

Was this helpful?
 
Leave a comment


This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

Try DigitalOcean for free

Click below to sign up and get $200 of credit to try our products over 60 days!

Sign up

Join the Tech Talk
Success! Thank you! Please check your email for further details.

Please complete your information!

Become a contributor for community

Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

DigitalOcean Documentation

Full documentation for every DigitalOcean product.

Resources for startups and SMBs

The Wave has everything you need to know about building a business, from raising funding to marketing your product.

Get our newsletter

Stay up to date by signing up for DigitalOcean’s Infrastructure as a Newsletter.

New accounts only. By submitting your email you agree to our Privacy Policy

The developer cloud

Scale up as you grow — whether you're running one virtual machine or ten thousand.

Get started for free

Sign up and get $200 in credit for your first 60 days with DigitalOcean.*

*This promotional offer applies to new accounts only.