1

I am trying to test my Home.js component which gets an input of two numbers and by clicking Add button, the result appears on the screen.

Note that index.js looks EXACTLY the same as the Home.js component and this how they look like:

import 'bootstrap/dist/css/bootstrap.css';
import 'bootstrap/dist/css/bootstrap-theme.css';
import React from 'react';
import ReactDOM from 'react-dom';
import { LogOutButton } from './LogOutButton.js';

class Home extends React.Component {
displayName = Home.name;

state = {
  result: 0,
  val1: 0,
  val2: 0,
};

handleChangeOne = event => {
  this.setState({ val1: event.target.value });
};

handleChangeTwo = event => {
  this.setState({ val2: event.target.value });
};

add = () => {
  this.setState({ 
    result: parseInt(this.state.val1) + parseInt(this.state.val2)
  });
};

onLogoutClick = () => {
  window.location.href = 'https://www.MICROSOFT.com';
}

render() {
  return (
    <div>
      <h1>Hello world! The result is: {this.state.result}</h1>
      <input type="text" onChange={this.handleChangeOne} />
      +
      <input type="text" onChange={this.handleChangeTwo} />
      = <br />
      <button onClick={this.add}>Add</button>
      <br/><br/> 
      <LogOutButton onLogout={this.onLogoutClick} /> 
    </div>
  );
}
}

  export default Home;
  const rootElement = document.getElementById("root");
  ReactDOM.render(<Home />, rootElement);

The test checks that for any 2 given numbers, the user receives the right sum.

import React from 'react';
import { shallow } from 'enzyme'
import ReactDOM from 'react-dom';
import App from './App';
import { Home } from './components/Home';

describe('Home />', () => {
  it('Renders a sum', () => {
      const home = shallow(<Home />);
      var first_value = home.state().val1;
      var second_value = home.state().val2;
      var result = first_value + second_value;
      expect(result).toBe(0);

      const inputs = home.find('input');
      inputs.at(0).simulate('change', {target: {value: 5} } );
      inputs.at(1).simulate('change', { target: { value: 8 } });
      home.find('button').simulate('click');
      home.update();
      expect(home.state().result).toBe(13);
  });
});

The test worked perfectly but now something is going wrong and this is the error that I get after running the test:

 FAIL  src/Home.test.js
  ● Test suite failed to run

Invariant Violation: Target container is not a DOM element.

  50 |   export default Home;
  51 |   const rootElement = document.getElementById("root");
> 52 |   ReactDOM.render(<Home />, rootElement);
     |                    ^
  53 |
  54 |

  at invariant (node_modules/fbjs/lib/invariant.js:42:15)
  at renderSubtreeIntoContainer (node_modules/react-dom/cjs/react-dom.development.js:15180:34)
  at Object.render (node_modules/react-dom/cjs/react-dom.development.js:15290:12)
  at Object.<anonymous> (src/components/Home.js:52:20)
  at Object.<anonymous> (src/App.js:4:13)
  at Object.<anonymous> (src/Home.test.js:4:12)

I don't know what is the meaning of the pointer under

<Home />, rootElement); 

what's going on ?

jrz
  • 1,213
  • 4
  • 20
  • 54
  • This question might be a duplicate of [this question](https://stackoverflow.com/questions/39986178/testing-react-target-container-is-not-a-dom-element) – Rewire Nov 01 '18 at 10:12
  • I wonder are you importing the component properly. Should it not be `import Home from './components/Home';` – Paul Fitzgerald Nov 01 '18 at 10:14
  • @PaulFitzgerald I tried. it did not help the situation. – jrz Nov 01 '18 at 10:22

2 Answers2

3

From what you said that your tests run fine, I want to suggest that you separate this part of the Home component to its own file:

const rootElement = document.getElementById("root");
ReactDOM.render(<Home />, rootElement);

That way you should be able to run your tests without that line interfering.

Also ensure that your element with the id="root" in your index.html file is not set on the body element. Reason being that by the time the script finishes execution, document element is not available yet.

Refer to this answer by @Dan Abramov here.

codejockie
  • 9,020
  • 4
  • 40
  • 46
  • Hi, I would appreciate you assistance here: https://stackoverflow.com/questions/53536427/jest-component-testing Thank You! – jrz Nov 29 '18 at 10:28
1

Error is happening as test environment doesn't provide the element with id="root". You can either go with a conditional check like

rootElement || document.createElement('div')

Or go by configuring JSDOM and enter your element with id="root" in the html you will specify.

Diljohn5741
  • 449
  • 2
  • 7