Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can anyone provide an example on React-Redux Jest testing?

Tags:

reactjs

jestjs

I'm having a really hard time learning how to use jest. All the tutorials i come across either teach you how to test a script that renders to dom such as <App /> with or without snapshots. Other tutorials goes over how to mock tests with inputs. but I cant seem to find tutorials that explains clearly and give examples that i can use.

For example the script from below i have an idea on how to test the render portion, but i don't know how to test the redux or the rest of the functions.

Could anyone give an example of how to test the below script that i can use as a reference for the rest of the files i need to test in my project?

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

import CustomSearch from '../Components/CustomSearch';
import CustomToolBar from '../Components/CustomToolBar';
import Table from '../Components/Table';
import InsertButton from '../Components/InsertButton';

import UserForm from './UserForm ';

import { fetchUsers, deleteUser } from '../../actions/users';
import setModal from '../../actions/modal';

import TableColumns from '../../constants/data/TableColumns';

class Users extends Component {
  constructor(props) {
    super(props);
    this.onInsert = this.onInsert.bind(this);
    this.onDelete = this.onDelete.bind(this);
    this.onEdit = this.onEdit.bind(this);
    this.props.fetchUsers({ accountId: this.props.userData.account.id, token: props.userData.token });
  }

  onDelete(row) {
    if (confirm(`Are you sure you want to delete user ${row.first} ${row.last}?`)) {
      this.props.deleteUser({
        registered: row.registered,
        id: row.id,
        accountId: this.props.userData.account.id,
        token: this.props.userData.token
      });
    }
  }

  onEdit(row) {
    console.log(row);
    const modal = () => (<UserForm data={row} isEdit />);
    this.props.setCurrentModal(modal, 'Existing User Form');
  }

  onInsert() {
    const modal = () => (<UserForm />);
    this.props.setCurrentModal(modal, 'Add New User');
  }

  render() {
    const options = {
      searchField: (props) => (<CustomSearch {...props} />),
      insertBtn: () => (<InsertButton onClick={this.onInsert} />),
      toolBar: (props) => (<CustomToolBar {...props} />),
      onDelete: this.onDelete,
      onEdit: this.onEdit,
    };
    return (
      <Table data={this.props.users} columns={TableColumns.USERS} options={options} title="Users" />
    );
  }
}

User.propTypes = {
  setCurrentModal: PropTypes.func.isRequired,
  fetchUsers: PropTypes.func.isRequired,
  deleteUser: PropTypes.func.isRequired,
  userData: PropTypes.object.isRequired,
  users: PropTypes.array,
};

const mapStateToProps = (state) => ({
  userData: state.userData.data,
  users: state.tableData.users,
});

const mapDispatchToProps = (dispatch) => ({
  fetchUsers: (data) => dispatch(fetchUsers(data)),
  deleteUser: (data) => dispatch(deleteUser(data)),
  setCurrentModal: (modal, title) => dispatch(setModal(modal, title, null, true)),
});

export default connect(mapStateToProps, mapDispatchToProps)(User);
like image 605
Eric Avatar asked Oct 17 '17 13:10

Eric


People also ask

Do you need Jest for React testing library?

Some familiarity with Jest as a test runner or framework is helpful but not required. Because Jest is pre-packaged with Create React App, you do not need to install it separately.

Is React testing difficult?

Tests in RTL are really slow. Especially if I have some async waitFor statements then it is very common that I have like 3-5 tests for one component and they take about 10 seconds to run. It is completely unacceptable for TDD approach since I need a quick feedback loop.

How do I test a component with redux?

Alternately pass in an already-created Redux store instance. Pass through additional options to RTL's original render function. Automatically wrap the component being tested with a <Provider store={store}> Return the store instance in case the test needs to dispatch more actions or check state.


1 Answers

You should test raw component because it's clear that redux works so you don't have to test it. If for some reason you want to test mapStateToProps or mapDispatchToProps export them as well and test them separately in isolation.

So if you export your raw component like this:

export { Users }; // here you export raw component without connect(...)
export default connect(mapStateToProps, mapDispatchToProps)(Users);

Then you can test it as a standard react component by importing named export, like

import { Users } from './Users';

describe('Users', () => ....
   it('should render', () => ...

If you would like to test connected component because you don't want shallow rendering and maybe you render a lot of nested connected components, you need to wrap your component with <Provider> and create a store for it.

You can help yourself by using redux-mock-store that will apply middlewares for you.

Everything is very well explained in official redux documentation in Recipes > Writing tests, so my proposal is to read the whole chapter carefully. You can read there also about testing action creators, reducers and even more advanced concepts.

To read more and get better background, I encourage to check these 2 comments below from official redux / react-redux repos.

enter image description here

Direct link to comment: https://github.com/reactjs/react-redux/issues/325#issuecomment-199449298


enter image description here

Direct link to comment: https://github.com/reactjs/redux/issues/1534#issuecomment-280929259


Related question on StackOverflow:

How to Unit Test React-Redux Connected Components?

like image 198
Dawid Karabin Avatar answered Sep 29 '22 10:09

Dawid Karabin