34

In my unit test, I want to test whether the parent component is successfully rendering its child component. Here is the code:

describe('Parent Component', () => {
  it('renders Child component', () => {
    const wrapper = shallow(<Parent store={store} />);
    expect(wrapper.find(Child).length).toEqual(1);
  });
});

Parent:

const Parent = observer(({ store }) => {
  const bookList = toJS(store.planets);
  return (
    <div>
      <div className={style.planet_container}>
        {bookList.map(book => {
          return <Child key={book.name} name={book.name} />;
        })}
      </div>
    </div>
  );
});

Above code is taken from here, but it's not working. I am getting the following error:

Expected 1, Received 0'

Where am I going wrong? I am using Enzyme 3.3 with Jest 23.1.0.

vsync
  • 118,978
  • 58
  • 307
  • 400
darKnight
  • 5,651
  • 13
  • 47
  • 87
  • You're trying to find a Child component inside a Child component. I think it should be something like this: `const wrapper = shallow();` – Isaac Jun 21 '18 at 21:05
  • That was a typo while copying code here. Fixed above. – darKnight Jun 21 '18 at 21:07
  • 3
    And are you importing that Child component in your test? if not, try this: `expect(wrapper.find('Child').length).toEqual(1);` or try to import the Child component. – Isaac Jun 21 '18 at 21:11
  • Yes I am importing it, but still not working – darKnight Jun 21 '18 at 21:14
  • 2
    Try to create your wrapper with `mount` bacause `shallow` doesn't render children. Check this out: https://github.com/airbnb/enzyme/issues/465#issuecomment-227697726 – Isaac Jun 21 '18 at 21:38
  • I think I got the issue. `Child` only renders when `bookList` has some data. So how can I mock the `bookList` array in my test? (See code above, I made changes) – darKnight Jun 21 '18 at 21:48
  • I created a gist to give you an idea, but im not sure if it works. https://gist.github.com/isafrus5/e648897868a608361410b1988388a0da – Isaac Jun 21 '18 at 22:08

5 Answers5

14

You can check whether a parent component has rendered its child component using containsMatchingElement().

Based on Enzyme docs:

Returns whether or not a patternNode react element matches any element in the render tree.

Your test should look like this:

describe('Parent Component', () => {
  it('renders Child component', () => {
    const wrapper = shallow(<Parent store={store} />);
    expect(wrapper.containsMatchingElement(<Child />)).toEqual(true);
  });
});
Scott Martin
  • 1,260
  • 2
  • 17
  • 27
Ekown
  • 438
  • 6
  • 12
7

Enzyme allows finding by a component's displayName:

From Enzyme API documentation:

const wrapper = shallow(<MyComponent />);
expect(wrapper.find('Foo')).to.have.lengthOf(1);

So, in order to test sure the Child component has been rendered you can simply reference it by its displayName.

You can print the wrapper's HTML string: console.log( wrapper.debug() )


In case your component is dynamic you can set its displayName to a fixed one, so the test would be more bulletproof:

const MyComponent = props.dynamicChildComponent;
MyComponent.displayName = 'Foo';
vsync
  • 118,978
  • 58
  • 307
  • 400
  • I want to achieve the same ,but using react testing library.How can I do that?? – CodeOfLife Jun 09 '20 at 06:07
  • @CodeOfLife - You aren't using *Enzyme*? – vsync Jun 09 '20 at 06:53
  • I am using react testing library – CodeOfLife Jun 09 '20 at 07:07
  • 2
    @CodeOfLife - this discussion here is only about `jest` + `enzyme`, for your question you need to either check if anyone else already asked this, and if not, open a new question. Asking new questions within comments of another is not good – vsync Jun 09 '20 at 11:28
4

Child is not rendering because you are not mocking the props (in this case the prop "store") correctly.

Try this:

it('renders Child component', () => {
  const wrapper = shallow( < Parent / > );
  wrapper.setProps({
    store: {
      planets: [{
          name: "name 1"
        }
      ]
    }
  });
  expect(wrapper.find(Child)).toHaveLength(1);
});
2

Try this:

describe('Parent Component', () => {
  it('renders Child component', () => {
    const wrapper = shallow(<Parent />);
    expect(wrapper.find(Child)).toHaveLength(1);
  });
});
1

If you want to check child component elements

 let wrapper1 = mount(<PersonalInfo {...personalInfodata} />);
    expect(wrapper1.find('ChildComponent').children(0).find('.description').text().length).toBeGreaterThan(0);

you can do something like this

Dan Patil
  • 771
  • 6
  • 15