-2

am just learning testing in React using shallow

I have a parent Component and a child component

The parent component has one state defined as:

const [searchOpen, setSearchOpen] = useState(false);

const performAnAction = () => {
  setSearchOpen(false);
}

const changeSearch = async () => {
  await setSearchOpen(true); 
};

and inside the return of this parent component is calling the child component, but it does check the condition flag searchOpen , like -

return (
  if(searchOpen &&
   <childComponent performAnAction= {performAnAction} changeSearch={changeSearch}/>
  }
)

where performAnAction is a function.

But in the parentComponent.test.js

it('should render the Child Component', async () => {
  const component = shallow(<ParentComponent {...props} />);
  const child = component.find('childComponent');
  expect(child).toBeDefined();
  await child.props().performAnAction();
});

But am getting this error:

Method “props” is meant to be run on 1 node. 0 found instead.

When I remove the flag, it's working as expected. But since on the page load it's false, I am not sure if it gets in the DOM or not.

So my guess is somehow we need to make the flag true in test case file, correct me if I'm wrong.

Guys this is very minimal code for you to understand, feel free to comment, if any issues, since am new in the platform

Orlyyn
  • 2,296
  • 2
  • 20
  • 32
Coder
  • 69
  • 8
  • 1
    Why did you expect that it *would* be found? It's only shown if `searchOpen` is `true`, you set `searchOpen` to `false` by default, and there's no interaction in the test that might cause `setSearchOpen` to be invoked for that value to change. It's not clear from your example under what circumstances you expect that to happen. – jonrsharpe Mar 24 '21 at 10:10
  • @jonrsharpe then why am getting the error and the error goes if i remove that condition? so there might be some interaction , correct me if am wrong? i do have another function that will make the flag true, and hence the child component renders – Coder Mar 24 '21 at 10:18
  • *"the error goes if i remove that condition "* - if course the error goes if you remove the condition, because them you *are* rendering the child component. Without conditional rendering, it's... not rendered conditionally. Again, why expect anything else? *"i do have another function that will make the flag true"* - please give a [mre] showing that too. – jonrsharpe Mar 24 '21 at 10:19
  • @jonrsharpe see initially on page load ,its false, and when have one action to make the flag true,but in test case am accessing the child component and its associated function – Coder Mar 24 '21 at 10:23
  • Yes, I understand all of that, that's what I said. What's unclear is why, *given* that it's false on page load and you don't seem to be taking any action that would make it change, you're checking if the child component is rendered and apparently being surprised that it's not. – jonrsharpe Mar 24 '21 at 10:23
  • @jonrsharpe now you can see the code , on page load its false and i do have a method to make it true and another one to make it false again. Is there anyway i can make the flag true from test file , and i guess that will help – Coder Mar 24 '21 at 10:27
  • 1
    But those methods are, as far as you're showing us, only passed to the child component, which **isn't being rendered**. So what is supposed to be able to invoke them? As far as we can tell the child component can never be shown, so writing a test that expects it to be shown is a waste of time. It seems pointless to discuss further - please go and think about the logic of what you're doing, how that component could actually be displayed, and if you still have a question give a proper [mre] not just scattered bits of code. – jonrsharpe Mar 24 '21 at 10:31

1 Answers1

0

In your return line, you are using the searchOpen variable, which is false by default on initialisation.

In your test, shallow(<ParentComponent {...props} />);, ParentComponent will have its searchOpen state initialised to false, that's why your return won't return the ChildComponent. The error is normal!

To be able to render the childComponent, you either need to

  1. Remove the condition
  2. Initialise searchOpen to true (with useState(true))
  3. Or call the changeSearch function in your test, to set the searchOpen variable to true:
it('should render the Child Component', async () => {
  const wrapper = shallow(<ParentComponent {...props} />);

  // Call changeSearch function to update searchOpen's value
  const parentComponent = wrapper.instance();
  parentComponent.changeSearch();
  wrapper.update(); // to update the component's state

  const child = wrapper.find('childComponent');
  expect(child).toBeDefined();
  await child.props().performAnAction();
});
Orlyyn
  • 2,296
  • 2
  • 20
  • 32