Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is shallow rendering in Jest unit tests in React?

In this video (2 mins):

https://egghead.io/lessons/react-testing-intro-to-shallow-rendering

at around the 1:40 mark, the narrator says "So as you can see, this object is only one level deep of our rendered output, and that makes writing unit tests a lot simpler because we only have to worry about the component, not the environment the component was rendered in."

What does he mean by "one level deep"? In the context of the CoolComponent example, what might a two level deep rendered output look like?

like image 356
Ghdfg Avatar asked Oct 23 '17 03:10

Ghdfg


1 Answers

When shallow rendering is used, Jest will not render child components but return them as defined — ergo "one level deep rendering".

An example:

const Icon = (props) => {
    const className = 'glyphicon glyphicon-' + props.type;
    return (
        <span className={className} ariaHidden={true}></span>
    )
};

const ButtonWithIcon = (props) => (
    <a className="btn btn-default">
        <Icon type={props.icon} />
        {props.label}
    </a>
);
  • When testing <ButtonWithIcon icon="plus" label="Add Item" /> with the default renderer, it will “expand” the <Icon /> contained inside the <ButtonWithIcon />:

    <a class="btn btn-default">
        <span class="glyphicon glyphicon-plus"></span>
        Add Thing
    </a>
    
  • When testing <ButtonWithIcon icon="plus" label="Add Item" /> with the shallow renderer, it won't render the <Icon /> contained inside the <ButtonWithIcon />:

    <a class="btn btn-default">
        <Icon type="plus" />
        Add Thing
    </a>
    

The benefit of shallow rendering lies here: should the HTML of the <Icon /> component ever be changed, the test for the parent <ButtonWithIcon /> component will still run fine as it expects an <Icon type="plus" /> child component, and not the <span class="glyphicon glyphicon-plus"></span> HTML.

like image 82
Bramus Avatar answered Sep 29 '22 19:09

Bramus