I have a component that has few useState hooks:
const [resizing, setResizing] = React.useState(false);
const [x, setX] = React.useState(0);
const [y, setY] = React.useState(0);
And in some places I am calling more than one hook at a time, for example here in onResize
, I am calling both setResizing
and setX
or setY
hook:
<ResizableBox
height={520}
width={370}
minConstraints={[370, 520]}
maxConstraints={[Infinity, Infinity]}
className={classes.resizable}
onResize={(e) => {
if (e.movementX !== 0) {
setResizing(true);
setX((prev) => prev + e.movementX);
} else if (e.movementY !== 0) {
setResizing(true);
setY((prev) => prev + e.movementY / 2);
}
}}
onResizeStop={() => {
setResizing(false);
}}
>
I am used to testing class components where it is easy to test state changes.
I would like to test it with something like this:
const setXSpy = jest.spyOn(React, 'setX');
const setYSpy = jest.spyOn(React, 'setY');
const setResizeSpy = jest.spyOn(React, 'setResize');
it('calls useState hooks correctly', () => {
resizableBox.props.onResize({movementX: 1});
expect(setXSpy).toHaveBeenCalledWith(1);
expect(setYSpy).not.toHaveBeenCalled();
expect(setResizeSpy).toHaveBeenCalledWith(true);
});
But, I am not sure how test hooks like that in this example?
Yes. In fact that's how it was designed to be used. You just can't conditionalize the calls to useState because the call order matters to React. The number of times you called useState is tracked and React expects the same amount of calls each time.
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.
Testing the useState Hook with Enzyme import React from "react"; const App= () => { const [name, setName] = React. useState(""); return ( <form> <div className="row"> <div className="col-md-6"> <input type="text" placeholder="Enter your name" className="input" onChange={(e) => { setName(e. target.
If you need to test a custom Hook, you can do so by creating a component in your test, and using your Hook from it. Then you can test the component you wrote. To reduce the boilerplate, we recommend using React Testing Library which is designed to encourage writing tests that use your components as the end users do.
You're testing the implementation details of that component which is not a good idea (you're basically coupling the test to that implementation, instead of using the test to determine that the component does what it is supposed to do).
Instead I would try and find a way to test the component as a user would and determine that the output is correct.
Start by integrating testing-library and then follow some of the patterns described here and here.
The question is, what are you trying to test? what is the expected outcome of this test and which behaviour will it cover?
LE: in your case, as I see you're trying to test React-Resizable, you can try and mouseDown
on the resize handle, then emit mouseMove
and mouseUp
and see if the right things happens (I don't see from the code what you are doing with the state values, what are you using them for)
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