React Note: Mount Rendering Test

Previously, we talked about smoke testing and shallow rendering test. In this React Note, we will be talking about the next method for testing your React components, which is called mount rendering test (or full DOM rendering test). Again, we will use Jest and Enzyme for this.

Mount Rendering Test

Mount rendering test is pretty similar with shallow rendering test. The only difference is that, unlike shallow rendering, mount rendering actually mounts your components in the DOM. 

Why mounting components in the DOM is important, you might ask.

For a couple of reasons. By mounting components in the DOM, you can utilize DOM's APIs and test your component's lifecycle (componentDidMount, etc.), state changes, and test components wrapped in Higher Order Components (HOC).

How to do it?

Follow step-by-step instructions below:

  1. Install Enzyme and its accompanying packages:
    npm install --save enzyme enzyme-adapter-react-16 react-test-renderer​
  2. Configure Enzyme by creating a file called setupTests.js in the src folder. The file's content:
    import { configure } from "enzyme";
    import Adapter from "enzyme-adapter-react-16";
    
    configure({adapter: new Adapter()});​
  3. Let's say we have a button and a card component called MyButton and MyCard. Here's what they look like:
    MyButton.js
    This is a simple Higher Order Component (HOC) that renders a single button that calls an onClick props when clicked and can also be disabled through props.
    // src/MyButton.js
    
    import React from "react";
    
    const MyButton = ({onClick, disabled}) => {
    
      return (
        <div>
          <button onClick={onClick} disabled={disabled}>MyButton</button>
        </div>
      );
    }
    
    export default MyButton;​
    MyCard.js
    This is a simple card component that contains an input text and a MyButton component. The input element will call onChange props when the input value is changed.
    // src/MyCard.js
    
    import React from "react";
    import MyButton from "./MyButton";
    
    const MyCard = ({onClick, onChange, disabled}) => {
    
      return (
        <div>
          <input name="input" type="text" onChange={onChange} />
          <MyButton onClick={onClick} disabled={disabled} />
        </div>
      );
    }
    
    export default MyCard;​
  4. To test MyCard, create a file called MyCard.test.js in the same folder as MyCard with the following content:
    // src/MyCard.test.js
    
    import React from "react";
    import MyCard from "./MyCard";
    import { mount } from "enzyme";
    
    describe("<MyCard />", () => {
    
      // Test #1
      it("should not called `onClick` props when button is disabled", () => {
        const mockCallback = jest.fn();
        const wrapper = mount(<MyCard disabled={true} onClick={mockCallback} />);
        wrapper.find("button").simulate("click"); // Shallow rendering fail #1
        expect(mockCallback.mock.calls.length).toEqual(0);  // Shallow rendering fail #2
      });
    });​
    There is only 1 test here. In this test, we want to make sure that onClick props is not called when the disabled props equals true. If we use shallow, instead of mount, there are two problems that we will encounter:
    1. shallow doesn't render HOC component (in this case, MyButton) and will fail in finding the button element (see the file above to see where shallow rendering will fail).
    2. shallow doesn't utilize DOM APIs (in this case, button's disabled property) and will still call onClick props when clicked (see the file above to see where shallow rendering will fail).
  5. Run the tests with the following commands:
    $ npm test
    // or
    $ npm test -- --coverage​

  

That's it for mount rendering test!