How to test React Redux application with Jest

How to test React Redux application with Jest

In this tutorial, we’re gonna look at step by step to test React Redux application with Jest. This will apply on the application that we have built before.

Configure Jest and Babel for testing

– Install jest-cli and babel-jest:


yarn add jest-cli babel-jest

– Open package.json, add scripts:


{
  ...,
  "scripts": {
    ...,
    "test": "jest"
  },
  "dependencies": {
    "jest-cli": "22.4.3",
    "babel-jest": "22.4.3"
  }
}

It helps us to run testing with cmd: yarn test.
For watching: yarn test --watchAll

– Open .babelrc, add "env":


{
    "presets": ...,
    "env": {
        "test": {
            "presets": [
                "env",
                "react"
            ]
        }
    },
    "plugins": ...
}

– Run cmd: yarn install.

Now, we can run test inside filename.test.js file.
In this tutorial, we will use Jest test(), expect(), .toBe() and .toEqual() methods.

For more functions and details, please visit: Jest API Reference.

Use test function

Under project src folder, create tree like this:

react-redux-test-jest-babel-example-structure

Create test data items

data/books.js:


export default [
    {
        id: '1',
        title: 'Origin',
        description: 'Origin thrusts Robert Langdon into the dangerous intersection of humankind’s two most enduring questions.',
        author: 'Dan Brown',
        published: 2017
    },
    {
        id: '2',
        title: 'Harry Potter and the Goblet of Fire',
        description: 'A young wizard finds himself competing in a hazardous tournament between rival schools of magic, but he is distracted by recurring nightmares.',
        author: 'J. K. Rowling',
        published: 2000
    },
    {
        id: '3',
        title: 'Harry Potter and the Deathly Hallows',
        description: 'The seventh and final novel of the Harry Potter series.',
        author: 'J. K. Rowling',
        published: 2007
    },
    {
        id: '4',
        title: 'The 100-Year-Old Man Who Climbed Out the Window and Disappeared',
        description: 'Allan Karlsson is about to celebrate his hundredth birthday, and a party is planned at his retirement home. Allan is alert despite his age, but is not interested in attending the party. Instead he climbs out the window and disappears.',
        author: 'Jonas Jonasson',
        published: 2009
    }
];

Actions Test

actions/books.test.js:


import { addBook, removeBook, editBook } from '../../actions/books';

test('should return addBook action', () => {
    const book = {
        title: 'Just a Title',
        description: 'This is a Book.',
        author: 'Anonymous',
        published: 1990
    };
    const action = addBook(book);
    expect(action).toEqual({
        type: 'ADD_BOOK',
        book: {
            ...book,
            id: expect.any(String)
        }
    });
});

test('should return removeBook action', () => {
    const action = removeBook({ id: '123id' });
    expect(action).toEqual({
        type: 'REMOVE_BOOK',
        id: '123id'
    });
});

test('should return editBook action', () => {
    const action = editBook('123id', { title: 'Just a Title', published: 1990 });
    expect(action).toEqual({
        type: 'EDIT_BOOK',
        id: '123id',
        updates: { title: 'Just a Title', published: 1990 }
    });
});

actions/filters.test.js:


import { filterText, startYear, endYear, sortBy, clear } from '../../actions/filters';

test('should return filterText action', () => {
    const text = 'text to filter';
    const action = filterText(text);
    expect(action).toEqual({
        type: 'FILTER_TEXT',
        text
    });
});

test('should return startYear action', () => {
    const action = startYear(2018);
    expect(action).toEqual({
        type: 'START_YEAR',
        startYear: 2018
    });
});

test('should return endYear action', () => {
    const action = endYear(2099);
    expect(action).toEqual({
        type: 'END_YEAR',
        endYear: 2099
    });
});

test('should return sortBy action', () => {
    const type = 'published';
    const action = sortBy(type);
    expect(action).toEqual({
        type: 'SORT_BY',
        sortType: type
    });
});

test('should return clear action', () => {
    const action = clear();
    expect(action).toEqual({
        type: 'CLEAR',
        defaultFilter: {
            text: '',
            sortBy: '',
            startYear: undefined,
            endYear: undefined
        }
    });
});

Reducers Test

reducers/books.test.js:


import booksReducer from '../../reducers/books';
import books from '../../test/data/books';

test('should add a Book', () => {
    const book = {
        id: '123id',
        title: 'Just a Title',
        description: 'This is a Book.',
        author: 'Anonymous',
        published: 1990
    };

    const action = {
        type: 'ADD_BOOK',
        book
    };

    const state = booksReducer(books, action);
    expect(state).toEqual([...books, book]);
});

test('should remove a Book', () => {
    const action = {
        type: 'REMOVE_BOOK',
        id: books[1].id
    };

    const state = booksReducer(books, action);
    expect(state).toEqual([books[0], books[2], books[3]]);
});

test('should not remove any Book', () => {
    const action = {
        type: 'REMOVE_BOOK',
        id: 'notAnId'
    };

    const state = booksReducer(books, action);
    expect(state).toEqual(books);
});

test('should edit a Book', () => {
    const description = 'This is a Book.';

    const action = {
        type: 'EDIT_BOOK',
        id: books[1].id,
        updates: {
            description: description
        }
    };

    const state = booksReducer(books, action);
    expect(state[1].description).toBe(description);
});

test('should not edit any Book', () => {
    const description = 'This is a Book.';

    const action = {
        type: 'EDIT_BOOK',
        id: 'notAnId',
        updates: {
            description: description
        }
    };

    const state = booksReducer(books, action);
    expect(state).toEqual(books);
});

reducers/filters.test.js:


import filtersReducer from '../../reducers/filters';

const currentState = {
    text: '',
    sortBy: '',
    startYear: undefined,
    endYear: undefined
};

test('should set text for filter', () => {
    const text = 'filter string';
    const action = {
        type: 'FILTER_TEXT',
        text
    };

    const state = filtersReducer(currentState, action);
    expect(state.text).toBe(text);
});

test('should set sortBy for filter', () => {
    const sortType = 'filterstring';
    const action = {
        type: 'SORT_BY',
        sortType
    };

    const state = filtersReducer(currentState, action);
    expect(state.sortBy).toBe(sortType);
});

test('should set startYear for filter', () => {
    const startYear = 1990;
    const action = {
        type: 'START_YEAR',
        startYear
    };

    const state = filtersReducer(currentState, action);
    expect(state.startYear).toBe(startYear);
});

test('should set endYear for filter', () => {
    const endYear = 1990;
    const action = {
        type: 'END_YEAR',
        endYear
    };

    const state = filtersReducer(currentState, action);
    expect(state.endYear).toBe(endYear);
});

test('should clear field for filter', () => {
    const clearState = {
        text: '',
        sortBy: '',
        startYear: undefined,
        endYear: undefined
    };

    const action = {
        type: 'CLEAR',
        defaultFilter: clearState
    };

    const state = filtersReducer(currentState, action);
    expect(state).toEqual(clearState);
});

Selector Test

selectors/books.test.js:


import getVisibleBooks from '../../selectors/books';
import books from '../../test/data/books';

test('should filter by text', () => {
    const filters = {
        text: 'harry',
        sortBy: 'published',
        startYear: undefined,
        endYear: undefined
    };

    const result = getVisibleBooks(books, filters);
    expect(result).toEqual([books[1], books[2]]);
});

test('should sort by published year', () => {
    const filters = {
        text: '',
        sortBy: 'published',
        startYear: undefined,
        endYear: undefined
    };

    const result = getVisibleBooks(books, filters);
    expect(result).toEqual([books[1], books[2], books[3], books[0]]);
});

test('should sort by title', () => {
    const filters = {
        text: '',
        sortBy: 'title',
        startYear: undefined,
        endYear: undefined
    };

    const result = getVisibleBooks(books, filters);
    expect(result).toEqual([books[2], books[1], books[0], books[3]]);
});

test('should filter by startYear', () => {
    const filters = {
        text: '',
        sortBy: 'published',
        startYear: 2005,
        endYear: undefined
    };

    const result = getVisibleBooks(books, filters);
    expect(result).toEqual([books[2], books[3], books[0]]);
});

test('should filter by text & startYear', () => {
    const filters = {
        text: 'harry',
        sortBy: 'published',
        startYear: 2005,
        endYear: undefined
    };

    const result = getVisibleBooks(books, filters);
    expect(result).toEqual([books[2]]);
});

test('should filter by endYear', () => {
    const filters = {
        text: '',
        sortBy: 'published',
        startYear: undefined,
        endYear: 2012
    };

    const result = getVisibleBooks(books, filters);
    expect(result).toEqual([books[1], books[2], books[3]]);
});

test('should filter by startYear & endYear', () => {
    const filters = {
        text: '',
        sortBy: 'published',
        startYear: 2008,
        endYear: 2012
    };

    const result = getVisibleBooks(books, filters);
    expect(result).toEqual([books[3]]);
});

Run & Check results

Run cmd: yarn test.
Console:

react-redux-test-jest-babel-example-results

Source Code

ReactReduxTest-JestBabel



By grokonez | April 22, 2018.

Last updated on March 31, 2021.



Related Posts


Got Something To Say:

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

*