How do you test components that are wrapped with multiple higher order components?

Viewed 916
import React from 'react'
import sinon from 'sinon'
import { mount } from 'enzyme'
import configureStore from 'redux-mock-store'
import FileListEditable from './index.js'
import {shallow} from 'enzyme'


const middlewares = []
const mockStore = configureStore(middlewares)
const initialState = {
  customer: {
    clientId:'123'
  }
}
const store = mockStore(initialState)

const minProps = {
  files: []
}
const removeFile = sinon.spy()

const wrapper = shallow(
  <FileListEditable
    store={store}
    {...minProps}
    removeFile={removeFile} />,
  {context: {store}})

test.skip('Component: <FileListEditable/>, renders', () => {
  expect(wrapper.length).toBe(1)
  expect(wrapper.find('Tag').length).toBe(0)
})

test.skip('Component <FileListEditable/>, Add and remove files', () => {
  wrapper.setProps({
    files: [
      {
        name: 'file1',
        extension: 'txt'
      },
      {
        name: 'file2',
        extension: 'txt'
      }
    ]
  })

  expect(wrapper.find('Tag').length).toBe(2)

  wrapper.find('Tag').at(0).find('button').simulate('click')
  expect(removeFile.called).toBe(true)
  expect(removeFile.args[0][0]).toBe(0)

  wrapper.find('Tag').at(1).find('button').simulate('click')
  expect(removeFile.args[1][0]).toBe(1)
})

test.skip('Component <FileListEditable/>, File from documents will have link to that document', () => {

  wrapper.setProps({
    files: [
      {
        name: 'file1',
        extension: 'txt',
        id: 'file-document-id'
      },
      {
        name: 'file2',
        extension: 'txt'
      }
    ]
  })

  expect(wrapper.find('Tag').at(0).find('a').length).toBe(1)
  expect(wrapper.find('Tag').at(1).find('a').length).toBe(0)
})

These tests do not work because FileListEditable is wrapped with injectIntl and one of our own created higher order component. Which means when I use shallow rendering it will render the InjectIntl component and if I use mount I have to dive two layers. But I just can't seem to get it right. Is there a general solution for testing components that are wrapped with higher order components without having to care about the higher order component?

1 Answers

Thank you Daniel Lizik for sharing the link https://github.com/airbnb/enzyme/issues/98#issuecomment-169761955

cited from the link:

Internally at Airbnb, we use a pattern like the following:

class MyComponent extends React.Component {
  ...
}
export default connect(MyComponent); // default export. used in your app.
export { MyComponent as PureMyComponent}; // pure component. used in tests

This will work fine with redux's connect function, but won't work out of the box with the decorator syntax. You could open a pull request to redux to have the @connect decorator expose the underlying wrapped component as a static prop like UnderlyingComponent or something like that

Does that help at all?

Related