Skip to content

Instantly share code, notes, and snippets.

@agiveygives
Created April 25, 2019 01:34
Show Gist options
  • Star 10 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save agiveygives/721785723a23fe997ba2df21561f37e3 to your computer and use it in GitHub Desktop.
Save agiveygives/721785723a23fe997ba2df21561f37e3 to your computer and use it in GitHub Desktop.
Testing React State with Hooks, Jest, and Enzyme
import React from 'react';
const TestComponent = () => {
const [count, setCount] = React.useState(0);
return (
<h3>{count}</h3>
<span>
<button id="count-up" type="button" onClick={() => setCount(count + 1)}>Count Up</button>
<button id="count-down" type="button" onClick={() => setCount(count - 1)}>Count Down</button>
<button id="zero-count" type="button" onClick={() => setCount(0)}>Zero</button>
</span>
);
}
export default TestComponent;
import React from 'react';
import Enzyme from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
import TestComponent from './FunctionalComponent';
Enzyme.configure({ adapter: new Adapter() });
describe('<TestComponent />', () => {
let wrapper;
const setState = jest.fn();
const useStateSpy = jest.spyOn(React, 'useState')
useStateSpy.mockImplementation((init) => [init, setState]);
beforeEach(() => {
wrapper = Enzyme.shallow(<TestComponent />);
});
afterEach(() => {
jest.clearAllMocks();
});
describe('Count Up', () => {
it('calls setCount with count + 1', () => {
wrapper.find('#count-up').props().onClick();
expect(setState).toHaveBeenCalledWith(1);
});
});
describe('Count Down', () => {
it('calls setCount with count - 1', () => {
wrapper.find('#count-down').props().onClick();
expect(setState).toHaveBeenCalledWith(-1);
});
});
describe('Zero', () => {
it('calls setCount with 0', () => {
wrapper.find('#zero-count').props().onClick();
expect(setState).toHaveBeenCalledWith(0);
});
});
});
@pavlobu
Copy link

pavlobu commented Sep 24, 2020

awesome! thanks for sharing.

in case if someone comes here from search engine results and still having issues with their implementation code:

You MUST use React.useState inside your functional component code!

DON'T do this:

import React, { useState ...}  from 'react';

...

const [count, setCount] = useState(0);

...

DO THIS instead:

import React from 'react';

...

const [count, setCount] = React.useState(0);

and the above example will work!

@imbudhiraja
Copy link

@pavlobu How we can mock multiple states?

@crisperpo
Copy link

crisperpo commented Jan 19, 2021

@pavlobu thank you so much!!!
I was about to get crazy

@mouhsinelonly
Copy link

@pavlobu thanks

@danisaurio
Copy link

danisaurio commented Jan 22, 2021

Thank you!! @pavlobu @adiveygives

@williameliel
Copy link

williameliel commented Feb 9, 2021

Thanks!
Anyone knows why does react/jest behaves this way. In some repositories I am able to do:

import React from 'react';
const mockSetState = jest.fn();
jest.mock('react', () => ({
  ...jest.requireActual('react'),
  useState: (initial) => [initial, mockSetState],
}));

and later

expect(mockSetState).toHaveBeenCalledWith(0);

However in some repos I cannot?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment