Enzyme Test Code Memory cleanup

Viewed 3342

I have been looking at a lot of examples for testing react and redux applications using Enzyme and Jest, and there are very few that even mention code cleanup. When using shallow or mount do you not explicitly need to call unmount or detach to try to keep the memory bloat and runtime down?

1 Answers

There is a case where we will want to use detach to cleanup. Let's look at the simple shallow and mount case first.

Assigning to variables

This 'simple' case is where we simply assign the render to a var/const/let.

If we look at the (cut down) example of using Jest and Enzyme from the Enzyme Github.

describe('<MyComponent />', () => {
  it('renders three <Foo /> components', () => {
    const wrapper = shallow(<MyComponent />);
    expect(wrapper.find(Foo)).to.have.lengthOf(3);
  });

  it('renders an `.icon-star`', () => {
    const wrapper = shallow(<MyComponent />);
    expect(wrapper.find('.icon-star')).to.have.lengthOf(1);
  });
});

We can see the shallow method being called and the result being assigned to a const. The result is a ShallowWrapper object.

As const has a block scope when the execution leaves the block it is defined - in this case the test arrow function - the Javascript engine will automatically deallocate the ShallowWrapper memory.

It's because of this we don't need to worry about unmounting - this is only used to test specific Component lifecycle methods.

Attaching Components to DOM

We can also attach components to the DOM.

If we look at the test case automatically generated by the create-react-scripts.

it('renders without crashing', () => {
  const div = document.createElement('div');
  ReactDOM.render(<App />, div);
  ReactDOM.unmountComponentAtNode(div);
});

This example doesn't use Enzyme, but it's the same concept as to when you use attachTo in the Enzyme mount function.

We can see our Component is being attached to a div in the document and then ReactDOM.unmountComponentAtNode being called to cleanup. This is actually what detach calls.

We need to do this cleanup because a reference to our rendered Component exists outside our block scope and therefore will not be deallocated when execution exits this block.

Related