Jonathan
Jonathan

Reputation: 469

How to check the value of a nested React component in a unit test with Enzyme and Jest

I'm new in testing and I would like to access to a const

const Label = ({ intl, data }) => {
    if (data && data.length === 0) {
        return <div>{intl.translate('no_data')}</div>
    }
    return null
}

The test file:

test('should return null when is data', () => {
    const component = shallow(<StatisticsGraph {...mockPropsForComponent} />)
    const label = component.find(Label)
    expect(label).toEqual(null)
})

The variable mockPropsForComponent has the variable data with some values. I want to know the value of Label for the test pass

Upvotes: 3

Views: 7047

Answers (1)

Emile Bergeron
Emile Bergeron

Reputation: 17430

There are different solutions, for different problems to solve.

Testing an isolated component

Isolate the Label component in its own file and export it.

const Label = ({ intl, data }) => {
    if (data && data.length === 0) {
        return <div>{intl.translate('no_data')}</div>
    }
    return null
};

export default Label;

Then, test it individually. Like Quentin mentioned, a component is just a function you can call. We could call it directly, but it would leak irrelevant implementation details to the test. Instead, we assume it's a component and test it as such.

import Label from './Label';

describe('Label component', () => {
  it('returns null when there is data', () => {
    // works but leaks implementation details
    expect(Label({ data: ['anything'] })).toEqual(null);

    // Implementation agnostic test
    const wrapper = shallow(<Label />);
    expect(wrapper.isEmptyRender()).toBe(true);
  });
});

Testing a composition of components

Since you're testing StatisticsGraph and that your Label component has no identifiable selector, you could use snapshots to make sure it's rendered correctly.

import React from 'react';
import { render } from 'enzyme';
import toJson from 'enzyme-to-json';

describe('StatisticsGraph component', () => {
  it('renders properly', () => {
      const wrapper = render(<StatisticsGraph {...mockPropsForComponent} />);
      expect(toJson(wrapper)).toMatchSnapshot();
  });
});

The snapshot artifact should be committed alongside code changes, and reviewed as part of your code review process. [...] On subsequent test runs Jest will simply compare the rendered output with the previous snapshot. If they match, the test will pass. If they don't match, either the test runner found a bug in your code that should be fixed, or the implementation has changed and the snapshot needs to be updated.

Testing a component manually

If we really want to test each component's part manually, we may want to change the Label to be easier to find.

const Label = ({ intl, data }) => (
  <div className="label">
    {Boolean(data && data.length === 0) && intl.translate('no_data')}
  </div>
);

Then, the component should be found and we can use .isEmpty() to check that it worked.

describe('StatisticsGraph component', () => {
  it('does not render a label when there is data', () => {
      const component = shallow(<StatisticsGraph {...mockPropsForComponent} />);
      const label = component.find(Label);
      expect(label.isEmpty()).toBe(true);
  });
});

Upvotes: 3

Related Questions