Jim Ade
Jim Ade

Reputation: 71

Jest/Enzyme test throws error when using hooks

I have a simple React component that uses the useState hook. This component works correctly in the application, but my Jest test gives me the error "Hooks can only be called inside the body of a function component". As far as I can tell, I am calling useState correctly and, again, it works fine when I run the application.

I am using version 16.8.4 of both react and react-dom, as verified by npm ls.

Here is the component in its entirety:

import React, {useState} from 'react';
import './ExampleComponent.css';

function ExampleComponent(props) {
  const [count, setCount] = useState(0);
  const handler = () => setCount(count + 1);
  return (
    <div className='example-component'>
      <span>This component is a test</span>
      <button onClick={handler}>Test</button>
      <input readOnly={true} value={count}></input>
    </div>
  );
};

export default ExampleComponent;

And here is the corresponding Jest test (using Enzyme):

import React from 'react';
import ExampleComponent from './ExampleComponent';

describe('<ExampleComponent />', () => {
  const options = {
    targetElementId: 'fake-element-id'
  };
  const wrapper = shallow(<ExampleComponent options={options} />);
  it('renders a div', () => expect(wrapper.find('div').exists()).toBe(true));
});

I had read in some sources that Enzyme does not work with hooks, but I have a co-worker who is not having the problem. I have compared our package.json files and webpack configs and can find no differences.

Upvotes: 1

Views: 2012

Answers (2)

Jim Ade
Jim Ade

Reputation: 71

It appears I was too eager. As of now (2019-03-12) Enzyme simply doesn't support React Hooks yet. While I was able to get my test running by using mount() rather than shallow() there seem to be other issues and I don't know when Enzyme will support these features. I will fall back to using an earlier version of React and miss out on hooks until either Enzyme supports them or we decide to stop using Enzyme.

Upvotes: 3

Valerii
Valerii

Reputation: 2317

I tried this code with the exact same version of the react ant it works. It looks like your have a problem related to specific enzyme version or enzyme configuration.

I tried it with "enzyme": "^3.9.0" and "enzyme-adapter-react-16": "^1.10.0"

import React from 'react';
import { shallow } from 'enzyme';
import * as Enzyme from "enzyme";
import Adapter from 'enzyme-adapter-react-16';
import {ExampleComponent} from './App';

Enzyme.configure({ adapter: new Adapter() });

describe('<ExampleComponent />', () => {
  const options = {
    targetElementId: 'fake-element-id'
  };
  const wrapper = shallow(<ExampleComponent options={options} />);
  it('renders a div', () => expect(wrapper.find('div').exists()).toBe(true));
});

Upvotes: 0

Related Questions