Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Find component by display name when the component is stateless functional, with Enzyme

I have the following components:

// Hello.js
export default (React) => ({name}) => {
  return (
    <div>
      Hello {name ? name : 'Stranger'}!
    </div>
  )
}

// App.js
import createHello from './Hello'

export default (React) => () => {
  const Hello = createHello(React)
  const helloProps = {
    name: 'Jane'
  }
  return (
    <Hello { ...helloProps } />
  )
}

// index.js
import React from 'react'
import { render } from 'react-dom'
import createApp from './App'

const App = createApp(React)

render(
  <App />,
  document.getElementById('app')
)

And I want to set up a test to see if the App component contains one Hello component. I tried the following, using Tape and Enzyme:

import createApp from './App'
import React from 'react'
import test from 'tape'
import { shallow } from 'enzyme'

test('App component test', (assert) => {
  const App = createApp(React)
  const wrapper = shallow(<App />)
  assert.equal(wrapper.find('Hello').length === 1, true)
})

But the result was that the length property of the find result was equal to 0, when I was expecting it to be equal to 1. So, how do I find my Hello component?

like image 922
Marcus Vinícius Monteiro Avatar asked Feb 14 '16 16:02

Marcus Vinícius Monteiro


1 Answers

There are a couple of things you can do in this case. Enzyme can match component constructors based on the constructor's static .displayName or .name properties, or by referential equality. As a result, the following approaches should all work:

Direct Reference

you can import the actual components in your tests and find them using direct references to the component:

// NavBar-test.js

import NavBar from './path/to/NavBar';  
...  
wrapper.find(NavBar).length)

Named Function Expressions

If you use named function expressions to create your stateless functional components, the names should still work.

// NavBar.js  

module.exports = function NavBar(props) { ... }

Static .displayName property

You can add a static .displayName property on the components:

// NavBar.js

const NavBar = (props) => { ... };
NavBar.displayName = 'NavBar';
like image 95
Leland Richardson Avatar answered Sep 29 '22 22:09

Leland Richardson