React ~ Testing ~ Enzyme - rohit120582sharma/Documentation GitHub Wiki

Introduction

Enzyme is a testing utility for React Apps.

It creates virtual DOM without browser for testing.

It provides API wrappers that makes it easier to assert, manipulate, and traverse your React Components’ DOM. Enzyme can work with any testing framework, such as Jest or Mocha.

References



Setup

Installation

If you are wanting to use enzyme with React 16, but don't already have React 16 and react-dom installed, you should do so:

npm i --save react@16 react-dom@16

Next, to get started with enzyme, you can simply install it with npm. In order to use the most current version of React > 16, need to install "enzyme adapters" to provide full compatibility with React.

npm i --save-dev [email protected] enzyme-adapter-react-16 enzyme-to-json

Enzyme requires react-test-renderer for React apps version 15.5 or greater and including some peer dependencies:

npm i --save-dev react-test-renderer

React Test Renderer provides a React renderer that can be used to render React components to pure JavaScript objects, without depending on the DOM or a native mobile environment.


Setup file

Finally, add a setup file (test/setupTests.js) to configure the enzyme adapter for our tests. The disableLifecyleMethods portion is needed to allow us to modify props through different tests:

/**
 * setupTests.js
 * For react-native
 */
import 'react-native';
import 'jest-enzyme';
import Enzyme from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
import 'whatwg-fetch';

/**
 * Set up DOM in node.js environment for Enzyme to mount to
 */
const { JSDOM } = require('jsdom');

const jsdom = new JSDOM('<!doctype html><html><body></body></html>');
const { window } = jsdom;

function copyProps(src, target) {
    Object.defineProperties(target, {
        ...Object.getOwnPropertyDescriptors(src),
        ...Object.getOwnPropertyDescriptors(target),
    });
}

global.window = window;
global.document = window.document;
global.navigator = {
    userAgent: 'node.js',
};
copyProps(window, global);



/**
 * Set up Enzyme to mount to DOM, simulate events,
 * and inspect the DOM in tests.
 */
Enzyme.configure({
    adapter: new Adapter(),
    disableLifecycleMethods: true,
});



/**
 * Mock modules
 */
// react-native-languages
jest.mock('react-native-languages', () => {
    return {
        RNLanguages: {
            language: 'en',
            languages: ['en']
        }
    };
});
// react-native-cookies
jest.mock('react-native-cookies', () => {
    return {
        get: jest.fn().mockImplementation(() => {
            return Promise.resolve(true);
        }),
        set: jest.fn().mockImplementation((value) => {
            return Promise.resolve(value);
        }),
        setFromResponse: jest.fn().mockImplementation((value) => {
            return Promise.resolve(value);
        })
    };
});
// react-native-code-push
jest.mock('react-native-code-push', () => {
    function codepush(){
        return () => {};
    }
    codepush.CheckFrequency = {
        IMMEDIATE: 'IMMEDIATE'
    };
    codepush.sync = () => {};
    return codepush;
});
// Animated
jest.mock('Animated', () => {
    const ActualAnimated = require.requireActual('Animated')
    return {
      ...ActualAnimated,
      timing: (value, config) => ({
        start: callback => {
          value.setValue(config.toValue)
          if (callback) {
            callback()
          }
        },
      }),
    }
});
// react-native-navigation
jest.mock('react-native-navigation', () => {
    return {
        Navigation: {
            registerComponent: jest.fn(),
            pop: jest.fn()
        }
    };
});



/**
 * Ignore some expected warnings
 * see: https://jestjs.io/docs/en/tutorial-react.html#snapshot-testing-with-mocks-enzyme-and-react-16
 * see https://github.com/Root-App/react-native-mock-render/issues/6
 */
const originalConsoleError = console.error;
console.error = (message) => {
    if(message.startsWith('Warning:') ||
        message.startsWith('uncaught at') ||
        message.startsWith('The above error')){
        return;
    }
    originalConsoleError(message);
};

To run the setup file to configure Enzyme and the Adapter with Jest, set setupTestFrameworkScriptFile in your config file:

/**
 * jest.config.js
 */
module.exports = {
    ...
    "setupTestFrameworkScriptFile": "<rootDir>src/test/setupTests.js",
}


Enzyme API

Enzyme API focusses on rendering the react component and retrieving specific nodes from the rendered tree. There are three ways to render a component.

  • Shallow: Renders only the current component. It is useful in isolating testing to the current component and not testing/asserting the children component nested within.
  • Mount: Renders the full component in JSDom (a headless browser) and useful when full lifecycle is required to fully test the component.
  • Render: Renders the component as static HTML.

There are several methods to search through the DOM or retrieve nodes from the rendered component.

  • find: accepts a selector and retrieves nodes that match the selector.
  • findWhere: retrieve nodes selected by the predicate.
  • some: returns true if there is at-least one node matching the selector.
  • someWhere: returns true if there is at-least one node selected by the predicate.
  • first: returns the first node of a set.
  • at: returns the nth node of a set.
  • html: gets the HTML of the node.
  • text: gets the text representation of the node.

There are more methods to interact with the component and retrieve the component state.

  • simulate: simulates an event.
  • setProps: sets the props.
  • setState: sets the state.
  • setContext: sets the context.
  • prop(key): retrieves prop value corresponding to the provided key.
  • state(key): retrieves state corresponding to the provided key.
  • context(key): retrieves context value corresponding to the provided key.
⚠️ **GitHub.com Fallback** ⚠️