Skip to content

Latest commit

 

History

History
122 lines (100 loc) · 3.53 KB

README.md

File metadata and controls

122 lines (100 loc) · 3.53 KB

Test React components and dom using Enzyme

In this lesson we test the functionality of a React components using Jest and Ezyme.

  • We start off by installing jest, types for jest, typescript preprocessor for jest, enzyme, types for enzyme, and an adator for enzyme for our react version to our example react typescript application.
npm i jest @types/jest ts-jest enzyme @types/enzyme enzyme-adapter-react-16 -D

We configure jest using a simple jest.config.js file.

module.exports = {
  "roots": [
    "<rootDir>/src"
  ],
  "transform": {
    "^.+\\.tsx?$": "ts-jest"
  },
  "testRegex": "(/__tests__/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)$",
  "moduleFileExtensions": [
    "ts",
    "tsx",
    "js",
    "jsx",
    "json",
    "node"
  ],
  "setupTestFrameworkScriptFile": "<rootDir>/src/setupEnzyme.ts",
}

This file just tells jest that all our source is located in the src folder

  • For ts and tsx files we will be using ts-jest.
  • Jest should pickup files that end with .test
  • And that jest should pickup .ts and .tsx files as a part of its module lookup.
  • And a configuration file for enzyme.

Now in our configuraiton file src/setupEnzyme.ts we have some simple boiler plate to configure ezyme for react 16.

import { configure } from 'enzyme';
import * as EnzymeAdapter from 'enzyme-adapter-react-16';

configure({ adapter: new EnzymeAdapter() });

That is it for our jest and enzyme configuration.

Lets create a simple component that takes two props labelOn and labelOff and shows one of these strings based on whether an input checkbox is checked.

create checkboxWithLabel.tsx

import * as React from 'react';

export class CheckboxWithLabel extends React.Component<{
  labelOn: string,
  labelOff: string
}, {
    isChecked: boolean
  }> {
  constructor(props) {
    super(props);
    this.state = { isChecked: false };
  }

  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>
    );
  }
}

Here is quick look at its behaviour in the dom

import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { CheckboxWithLabel } from './checkboxWithLabel';

ReactDOM.render(
  <CheckboxWithLabel labelOn="on" labelOff="off"/>,
  document.getElementById('root')
);

npm start The text of the checkbox changes as we click the component. Such internal state, dom based component are exactly what enzyme is designed to test.

import * as React from 'react';
import { shallow } from 'enzyme';
import { CheckboxWithLabel } from './checkboxWithLabel';

test('CheckboxWithLabel changes the text after click', () => {
  const checkbox = shallow(<CheckboxWithLabel labelOn="On" labelOff="Off" />);
  expect(checkbox.text()).toEqual('Off');
  checkbox.find('input').simulate('change');
  expect(checkbox.text()).toEqual('On');
});
  • Next we create a checkboxWithLabel.test.tsx test file.
  • We bring in react, shallow from enzyme, and our component
  • Our test will do a shallow rendering of the component
  • We expect the initial text to be off
  • We can do dom interactions on the checkbox by simple selector queries and simulated actions.
  • We now expect the checkbox to have the new text based on the user's change interaction.

We run the test using npx jest and you can see that it works as expected.