jest + enzyme, using mount(), document.getElementById() returns null on component which appear after _method call jest + enzyme, using mount(), document.getElementById() returns null on component which appear after _method call reactjs reactjs

jest + enzyme, using mount(), document.getElementById() returns null on component which appear after _method call


Found the solution thanks to https://stackoverflow.com/users/853560/lewis-chung and gods of Google:

  1. Attached my component to DOM via attachTo param:

    const result = mount(    <App />, { attachTo: document.body });
  2. Changed buggy string in my method to string which works with element Object

agentToMod.location = locationSelect.options[locationSelect.selectedIndex].text;` : _modifyAgentStatus () {    const { currentAgentProfile, agentsDatabase } = this.state;    const agentToMod = currentAgentProfile;    if (agentToMod.status === 'Free') {        this.setState({            infoDisplayContent: 'mission'        });        agentToMod.status = 'Waiting';    } else if (agentToMod.status === 'Waiting') {        const locationSelect = document.getElementById('missionLocationSelect');        agentToMod.location = agentToMod.location = locationSelect.options[locationSelect.selectedIndex].text;        agentToMod.status = 'On Mission';        this.setState({            infoDisplayContent: 'profile'            });        }    }


attachTo: document.body will generate a warning:

Warning: render(): Rendering components directly into document.body is discouraged, since its children are often manipulated by third-party scripts and browser extensions. This may lead to subtle reconciliation issues. Try rendering into a container element created for your app.

So just attach to a container element instead of document.body, and no need to add it to the global Window object

before(() => {  // Avoid `attachTo: document.body` Warning  const div = document.createElement('div');  div.setAttribute('id', 'container');  document.body.appendChild(div);});after(() => {  const div = document.getElementById('container');  if (div) {    document.body.removeChild(div);  }});it('should display all contents', () => {  const wrapper = mount(<YourComponent/>,{ attachTo: document.getElementById('container') });});


Attached your component to DOM via attachTo param.

import { mount} from 'enzyme';// Avoid Warning: render(): Rendering components directly into document.body is discouraged.beforeAll(() => {  const div = document.createElement('div');  window.domNode = div;  document.body.appendChild(div);})test("Test component with mount + document query selector",()=>{  const wrapper = mount(<YourComponent/>,{ attachTo: window.domNode });});

why we need this?

mount only render component to div element not attached it to DOM tree.

// Enzyme code of mount renderer. createMountRenderer(options) {    assertDomAvailable('mount');    const domNode = options.attachTo || global.document.createElement('div');    let instance = null;    return {      render(el, context, callback) {        if (instance === null) {          const ReactWrapperComponent = createMountWrapper(el, options);          const wrappedEl = React.createElement(ReactWrapperComponent, {            Component: el.type,            props: el.props,            context,          });          instance = ReactDOM.render(wrappedEl, domNode);          if (typeof callback === 'function') {            callback();          }        } else {          instance.setChildProps(el.props, context, callback);        }      },      unmount() {        ReactDOM.unmountComponentAtNode(domNode);        instance = null;      },      getNode() {        return instance ? instanceToTree(instance._reactInternalInstance).rendered : null;      },      simulateEvent(node, event, mock) {        const mappedEvent = mapNativeEventNames(event);        const eventFn = TestUtils.Simulate[mappedEvent];        if (!eventFn) {          throw new TypeError(`ReactWrapper::simulate() event '${event}' does not exist`);        }        // eslint-disable-next-line react/no-find-dom-node        eventFn(ReactDOM.findDOMNode(node.instance), mock);      },      batchedUpdates(fn) {        return ReactDOM.unstable_batchedUpdates(fn);      },    };  }