Testing ES6 React components with Enzyme's shallow rendering

I ran into a strange issue today when writing some assertions using the Enzyme testing library for React.

Whenever I create a new component, I like to use ES6 class notation and export the class anonymously like this:

// MyChildComponent.js
import React from 'react';

export default class extends React.Component {
  render() {
    return (<div>MyChildComponent</div>)
  }
}

Then, I'll render it in another component like this:

// MyParentComponent.js
import React from 'react';
import MyChildComponent from './MyChildComponent';

export default class extends React.Component {
  render() {
    return (
      <div>
        <MyChildComponent />
      </div>
    )
  }
}

When testing for the presence of MyChildComponent within MyParentComponent in Enzyme, I'll typically produce a test that looks like this:

import { shallow } from 'enzyme';
import { expect } from 'chai';

import MyParentComponent from './MyParentComponent';

describe("<MyParentComponent />", () => {

  const wrapper = shallow(<MyParentComponent />);

  it("renders a MyChildComponent", () => {
    expect(wrapper.find('MyChildComponent')).to.have.length(1);
  });

});

But this fails! It's as if MyChildComponent isn't being rendered at all.

If I dump wrapper.debug() (doc) to the console, I get this output in place of MyChildComponent:

<div>
<_class />
</div>

It's as if Enzyme doesn't know the component is called MyChildComponent!

Solutions

There are two ways to solve this.

Import the component itself and assert on it instead

Below, we import MyChildComponent and then, in the assertion, use the class constant instead of the string literal "MyChildComponent":

import { shallow } from 'enzyme';
import { expect } from 'chai';

import MyParentComponent from './MyParentComponent';
import MyChildComponent from './MyChildComponent';

describe("<MyParentComponent />", () => {

  const wrapper = shallow(<MyParentComponent />);

  it("renders a MyChildComponent", () => {
    expect(wrapper.find(MyChildComponent)).to.have.length(1);
  });

});

Export the named class from within the child component

As much as we should strive to write code that doesn't repeat itself, this was the solution I ultimately chose. It turns out React is able to determine the class name so long as you define it in the class statement. Modifying MyChildComponent.js to produce a named class and then exporting it allows Enzyme to find it in the string literal assertion:

// MyChildComponent.js
import React from 'react';

class MyChildComponent extends React.Component {
  render() {
    return (<div>MyChildComponent</div>)
  }
}

export default MyChildComponent;

If you can't seem to get an Enzyme assertion to find a component you know is there, make sure Enzyme knows what sort of component it is!