user2800382
user2800382

Reputation: 259

Testing React Components that get state + setState properties passed by parent

How would you test React components that accept state hooks as properties?

For example

In the app, this ChildComponent is rendered like so:

<App>
   <OtherComponent />

   <div>
      <ChildComponent selectedProperty={selectedProperty} 
         setSelectedProperty={setSelectedProperty} /> 
   </div>
</App>

In my test, i'm trying to do this:

component = await render(
 <ChildComponent selectedProperty={selectedProperty} 
   setSelectedProperty={setSelectedProperty} /> 
);

However I don't know how I would pass in these two properties selectedProperty and setSelectedProperty which in the app is handled by the parent component.

Thank you.

Upvotes: 6

Views: 9013

Answers (1)

lmat - Reinstate Monica
lmat - Reinstate Monica

Reputation: 7768

As a minimum example, fulfilling only the requirements you specified, this should work:

const selectedProperty = 'whatever';
const setSelectedProperty = () => {};
component = await render(
 <ChildComponent selectedProperty={selectedProperty} 
   setSelectedProperty={setSelectedProperty} /> 
);

In case you need to verify that ChildComponent actually called setSelectedProperty, you can use a jest mock.

const selectedProperty = 'whatever';
const setSelectedProperty = jest.fn();
component = await render(
 <ChildComponent selectedProperty={selectedProperty} 
   setSelectedProperty={setSelectedProperty} /> 
);
expect(setSelectedProperty).toHaveBeenCalled();

And of course, the whole of Jest function mocks are available to you (documented here: https://jestjs.io/docs/mock-functions).

------ Edit -------

I think you're actually asking: "How can I change state passed to a component in response to that component calling a set...?". Excellent question! You can either not (see more below) or check answers to this question: How to test a prop update on React component

The reason I would suggest to not to is because 1. your test is growing too much and 2. it's not necessary. Presumably you want to test two things:

  1. When something happens, setSelectedProperty is called, and
  2. The component renders properly for different values of selectedProperty.

There is no need to test those together; test them separately. If your component holds so much state that you feel you need to test them together, it may be that your component is too stateful. React should be as "functional" as possible and without side effects. If your component is becoming unmanageable and difficult to test in this regard, don't give up testing, redesign the component.

Upvotes: 6

Related Questions