enzymejs/enzyme

wrapper.instance() throws error after wrapper.unmount()

Open

#956 opened on May 25, 2017

View on GitHub
 (6 comments) (0 reactions) (0 assignees)JavaScript (19,979 stars) (2,016 forks)batch import
API: mountbughelp wanted

Description

When calling wrapper.instance() after wrapper.unmount() it throws TypeError: component.getPublicInstance is not a function

The use-case for accessing the React component instance after the unmount is to check that any possible teardown in componentWillUnmount() has been successful. In my particular use-case I want to check that an RxJS Subscription has been unsubscribed.

Code to reproduce:

import React from 'react';
import Rx from 'rxjs';
import { mount } from 'enzyme';

class MyComponent extends React.Component {

  constructor() {
    super();
    this.state = {
      foo: 'initial'
    };
  }

  componentDidMount() {
    this.subscription = this.props.subject.subscribe(
      value => this.setState({ foo: value })
    );
  }

  componentWillUnmount() {
    this.subscription.unsubscribe();
  }

  render() {
    return <div>{ this.state.foo }</div>;
  }
}

it('unsubscribes on unmount', () => {
  const subject = new Rx.BehaviorSubject('new value');

  const wrapper = mount(
    <MyComponent subject={subject} />,
  );
  expect(wrapper.instance()).toHaveProperty('subscription.closed', false);
  wrapper.unmount();
  expect(wrapper.instance()).toHaveProperty('subscription.closed', true);
});

Test output:

FAIL  src/ui/memo/__tests__/AfterUnmount.test.js
  ● unsubscribes on unmount

    TypeError: component.getPublicInstance is not a function
      
      at WrapperComponent.getInstance (node_modules/enzyme/build/ReactWrapperComponent.js:81:32)
      at ReactWrapper.instance (node_modules/enzyme/build/ReactWrapper.js:219:31)
      at Object.<anonymous>.it (src/ui/memo/__tests__/AfterUnmount.test.js:37:18)
      at Promise.resolve.then.el (node_modules/p-map/index.js:42:16)
      at process._tickCallback (internal/process/next_tick.js:103:7)

There is a workaround by using wrapper.node instead of wrapper.instance() in the last expect: expect(wrapper.node).toHaveProperty('subscription.closed', true);. But this feels dirty because .node is an undocumented feature.

Used versions: enzyme: 2.8.2 jest: 20.0.3 react: 15.5.4 react-scripts: 1.0.5 rxjs: 5.4.0 enzyme-to-json: 1.5.1 (I don't think this affects this particular test, but I had it installed anyway)

Contributor guide