Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React hooks - how to test multiple useState hooks

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?

like image 278
Leff Avatar asked Sep 10 '20 08:09

Leff


People also ask

Can I use multiple useState in React?

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.

How do you mock a useState in jest?

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.

How do you test for enzyme Hooks?

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.

How do you test React Hooks?

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.


1 Answers

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)

like image 142
tudor.gergely Avatar answered Sep 25 '22 04:09

tudor.gergely