Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Finding the number of rendered child components in react test using enzyme?

I've spent all day diving into the Enzyme docs and starting to get the hang of the basics.

I'm looping through some data in my Redux store to render these nested <BudgetWidgetCard /> components into my parent component and want to ensure that X of them are getting rendered to the page.

Component Example

  <div>
    <main className="col-sm-9 offset-sm-3 col-md-10 offset-md-2 pt-3">
      <h1 name='main-header-title'>{metaProperties.pageTitle}</h1>
      {budgetWidgets.map((widget, i) => {
        return <BudgetWidgetCard className='budget-widget' title={widget} key={i} state={this.props} />
      })}
</main>
</div>

Test Approach

  it('+++renders the budget widget items correctly', () => {
      console.log(wrapper.children().children().filter('budget-widget').length)
      console.log(wrapper.find(<BudgetWidgetCard />).forEach(child => {
        console.log(child.text())
      }))
    })

I don't like the idea of calling children().children()... seems tightly coupled, but maybe that is the approach to go. My end goal is to simplistically state that the shallow render of componentA has X number of <BudgetWidgetCards />

I get the following output:

Review Current Budget<BudgetWidgetCard /><BudgetWidgetCard /><BudgetWidgetCard /><BudgetWidgetCard />Add A New Budget Item<ReduxForm /><BudgetTable />

When using the following:

  wrapper.children().forEach(child=> {
    console.log(child.text())
  })

Test File

import React from 'react'
import { shallow, mount } from 'enzyme';
import renderer from 'react-test-renderer'
// import configureStore from 'redux-mock-store'
import {Provider} from 'react-redux'
import {createStore} from 'redux'
import { MemoryRouter as Router, withRouter } from 'react-router-dom';
import { configure } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
import { configureStore } from '../src/configuration/store';
configure({ adapter: new Adapter() });

/**
BUDGET COMPONENTS
**/
import Budget from '../src/Budget/components/Budget';
import BudgetWidgetCard from '../src/Budget/components/Budget';

let mainHeaderTitle = 'Review Current Budget';
const store = configureStore();
const wrapper = shallow(<Budget />);

// Snapshot for Budget React Component
describe('>>>B U D G E T --- Snapshot',()=>{
  it('+++capturing Snapshot of Budget', () => {
      const wrapper = shallow(<Budget />);
      expect(wrapper).toMatchSnapshot();
    })
});

describe('>>>B U D G E T --- Elements Getting Rendered Correctly',()=>{
  it('+++correct title is getting rendered as header', () => {
      expect(wrapper.find('h1[name="main-header-title"]').text()).toEqual(mainHeaderTitle);
    })

  it('+++renders the budget widget items correctly', () => {
      expect(wrapper.children().find(BudgetWidgetCard).length).toE‌​qual(4)
    })
});
like image 537
John Lippson Avatar asked Jan 10 '18 21:01

John Lippson


People also ask

How do I test that a child component is rendered?

By using enzyme you can check if a parent component rendered its child component. For this use containsMatchingElement(). Now you can test it like this: const wrapper = shallow();

How do you test if a child component is rendered React testing library?

You can use @testing-library/jest-dom library.

How would you test the React components using jest and enzymes?

Both Jest and Enzyme are meant to test the react applications. Jest can be used with any other Javascript framework, but Enzyme is meant to run on react only. Jest can be used without Enzyme, and snapshots can be created and tested perfectly fine. But the Enzyme adds additional functionality to it.

How do you find the value of child components?

We can get child component values in the parent component by creating a reference to the child component using the @ref directive in the Parent component. Using the reference instance, you can access the child component values in the parent.


2 Answers

I will address the title of the question and not the body, since others addressed the specific scenario described here already in great details, but I wish to focus on the broader aspect of the question, which is to count children:

Enzyme children() method allows that.

Returns a new wrapper with all of the children of the node(s) in the current wrapper. Optionally, a selector can be provided and it will filter the children by this selector

For example:

const wrapper = mount(<ToDoList items={items} />);
expect(wrapper.children()).to.have.length(items.length);

Assuming <ToDoList> component returns an element with varying number of children inside it.

like image 74
vsync Avatar answered Oct 26 '22 06:10

vsync


If you import the component you expect to be rendered x times you can do this:

expect(wrapper.find(BudgetWidgetCard)).to.have.length(x);

http://airbnb.io/enzyme/docs/api/ReactWrapper/find.html

like image 35
Galupuf Avatar answered Oct 26 '22 05:10

Galupuf