I'm new to React Hooks and what I'm trying to achieve is to test a React component (called CardFooter) that contains a call to useEffect hook that gets triggered a global context variable is modified.
CardFooter.js:
const CardFooter = props => {
const [localState, setLocalState] = useState({
attachmentError: false
});
const globalContext = useContext(GlobalContext);
React.useEffect(()=> {
setLocalState({
...localState,
attachmentError: globalContext.data.attachmentError
});
},[globalContext.data.attachmentError]);
}
CardFooter.test.js:
import Enzyme, { shallow } from 'enzyme';
Enzyme.configure({ adapter: new Adapter() });
describe('<CardFooter />', () => {
let useEffect;
const mockUseEffect = () => {
useEffect.mockImplementation(f => f());
};
useEffect = jest.spyOn(React, "useEffect");
mockUseEffect(); //
it('should render correctly with no props.', () => {
}
const mockUseEffect = () => {
useEffect.mockImplementation(f => f());
};
useEffect = jest.spyOn(React, "useEffect");
mockUseEffect();
const wrapper = shallow(<CardFooter />);
expect(toJson(wrapper)).toMatchSnapshot();
});
the error that I'm getting when running the test is:
TypeError: Cannot read property 'attachmentError' of undefined
I tried the approach presented here: https://medium.com/@pylnata/testing-react-functional-component-using-hooks-useeffect-usedispatch-and-useselector-in-shallow-9cfbc74f62fb . However it seems that shallow does not pick the mocked useEffect implementation. I also tried mocking the useContext and the globalContext.data.attachmentError. Nothing seems to work.
The spyOn function is one of the most powerful utility functions in Jest. It allows you to spy on a function, observe interactions, and mock them accordingly.
To enable us to mock useState, we use React. useState (line #5) instead of using the usual named import (i.e. import { useState } from 'react'). Below is our Jest unit test for the component. Before rendering the component for testing, we create a constant 'setStateMock' and mock it with a jest function jest.
To trigger the useEffect hook before unmounting the component from the screen, we can return a function from the callback function. The function returned by the callback will be executed before that component is unmounted.
To test the component update useEffect hook you'd simply trigger state updates and check for effects in rendered elements. Redux hooks can be tested by mocking them and their implementation.
Try this. Notice the "jest.spyOn" is placed inside "beforeEach"
beforeEach(() => {
jest.spyOn(React, "useEffect").mockImplementationOnce(cb => cb()());
// .... other things ....
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With