Skip to content

Instantly share code, notes, and snippets.

@binario200
Last active April 14, 2022 08:48
Show Gist options
  • Save binario200/4a272d7885dfb64b770b5199f6ac3a7a to your computer and use it in GitHub Desktop.
Save binario200/4a272d7885dfb64b770b5199f6ac3a7a to your computer and use it in GitHub Desktop.
How to test react components with Jest

Jest and react component testing

this quick tutorial helps to lear the basic of testing react components with Jest

first of all set up your react app, you can use create-react-app or do a general setup like this https://gist.github.com/binario200/35e13892875531d6eef6530dc5ca89aa

then install Jest and dependencies. // https://facebook.github.io/jest/docs/en/tutorial-react.html

npm install --save-dev jest babel-jest babel-preset-es2015 babel-preset-react react-test-renderer

Your package.json should look something like this (where is the actual latest version number for the package). Please add the scripts and jest configuration entries:

// package.json
  "dependencies": {
    "react": "<current-version>",
    "react-dom": "<current-version>"
  },
  "devDependencies": {
    "babel-jest": "<current-version>",
    "babel-preset-es2015": "<current-version>",
    "babel-preset-react": "<current-version>",
    "jest": "<current-version>",
    "react-test-renderer": "<current-version>"
  },
  "scripts": {
    "test": "jest"
  }

take care about the test script that is using jest.

Snapshot testing

Snapshot tests are a very useful tool whenever you want to make sure your UI does not change unexpectedly. A typical snapshot test case for a mobile app renders a UI component, takes a screenshot, then compares it to a reference image stored alongside the test. The test will fail if the two images do not match: either the change is unexpected, or the screenshot needs to be updated to the new version of the UI component.

A similar approach can be taken when it comes to testing your React components. Instead of rendering the graphical UI, which would require building the entire app, you can use a test renderer to quickly generate a serializable value for your React tree.

  • Create a test folder, where we will be adding our tests. Jest will run the tests from files in this folder.
mkdir __test__
  • for every component you whant to test create a file, we have to make sure that the file should end with .test.js so that Jest will pick up it to run the tests.
touch app.test.js
  • For a quick test try, a output notifying that it were not foud any tests.
npm test
  • Use Link.react.js component to create a snapshot test
  • Create the test file for Link.react, Link.react.test.js
  • run npm test again
npm test
  • Look how Jest creates the snapshots folder witht he snapshots (a capture of the component rendered output ) for each component test.

  • The next time you run the tests, the rendered output will be compared to the previously created snapshot. The snapshot should be committed along code changes. When a snapshot test fails, you need to inspect whether it is an intended or unintended change. If the change is expected you can invoke Jest with jest -u to overwrite the existing snapshot.

# to overwrite the existing snapshot
jest -u 

DOM Testing

If you'd like to assert, and manipulate your rendered components you can use Enzyme or React's TestUtils. You have to run npm install --save-dev enzyme to use Enzyme. If you are using a React below version 15.5.0, you will also need to install react-addons-test-utils.

npm install --save-dev enzyme react-addons-test-utils
  • Using enzyme shallow render Shallow rendering is useful to constrain yourself to testing a component as a unit, and to ensure that your tests aren't indirectly asserting on behavior of child components.

http://airbnb.io/enzyme/docs/api/shallow.html

  • Create the CheckboxWithLabel component
  • Create the CheckboxWithLabel.test.js test file.
  • look for methods like shallow(component) to render a checkbox in the document
  • check methods like .simulate('event') to simulate dom changes.

Behavior Drive Testing

https://gist.github.com/binario200/4a272d7885dfb64b770b5199f6ac3a7a

  • Thought Process
  • first tests usually verify that the state was correctly initialized.
  • test events that change the state, mock our functions, clear our mocks and create fake data here.
import React from 'react';
export default class CheckboxWithLabel extends React.Component {
constructor(props) {
super(props);
this.state = {isChecked: false};
// bind manually because React class components don't auto-bind
// http://facebook.github.io/react/blog/2015/01/27/react-v0.13.0-beta-1.html#autobinding
this.onChange = this.onChange.bind(this);
}
onChange() {
this.setState({isChecked: !this.state.isChecked});
}
render() {
return (
<label>
<input
type="checkbox"
checked={this.state.isChecked}
onChange={this.onChange}
/>
{this.state.isChecked ? this.props.labelOn : this.props.labelOff}
</label>
);
}
}
/* eslint-disable no-unused-vars */
import React from 'react';
import {shallow} from 'enzyme';
import CheckboxWithLabel from '../CheckboxWithLabel';
it('CheckboxWithLabel changes the text after click', () => {
// Render a checkbox with label in the document
const checkbox = shallow(<CheckboxWithLabel labelOn="On" labelOff="Off" />);
expect(checkbox.text()).toEqual('Off');
checkbox.find('input').simulate('change');
expect(checkbox.text()).toEqual('On');
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment