tleunen / react-mdl

React Components for Material Design Lite
https://tleunen.github.io/react-mdl/
MIT License
1.76k stars 255 forks source link

unit-test w/ jest #452

Closed brandonmp closed 7 years ago

brandonmp commented 7 years ago

Trying-out MDL in a create-react-app i've ejected (that is, a vanilla webpack/babel react app)

My test is pretty simple:

// component, which renders fine
class App extends Component {
  render() {
    return (
      <div style={{ height: '100vh', position: 'relative' }}>
        <Layout fixedHeader fixedDrawer>
        </Layout>
      </div>
    )
  }
}

it('renders without crashing', () => {
  const div = document.createElement('div')
  ReactDOM.render(<App />, div)
})

but at first it was throwing this:

TypeError: Cannot read property 'upgradeElement' of undefined

      at MDLComponent.componentDidMount (node_modules/react-mdl/lib/utils/MDLComponent.js:34:40)
      at node_modules/react-dom/lib/ReactCompositeComponent.js:265:25
      at measureLifeCyclePerf (node_modules/react-dom/lib/ReactCompositeComponent.js:75:12)
      at node_modules/react-dom/lib/ReactCompositeComponent.js:264:11
      at CallbackQueue.notifyAll (node_modules/react-dom/lib/CallbackQueue.js:76:22)
      at ReactReconcileTransaction.close (node_modules/react-dom/lib/ReactReconcileTransaction.js:80:26)
      at ReactReconcileTransaction.closeAll (node_modules/react-dom/lib/Transaction.js:206:25)
      at ReactReconcileTransaction.perform (node_modules/react-dom/lib/Transaction.js:153:16)
      at batchedMountComponentIntoNode (node_modules/react-dom/lib/ReactMount.js:126:15)
      at ReactDefaultBatchingStrategyTransaction.perform (node_modules/react-dom/lib/Transaction.js:140:20)
      at Object.batchedUpdates (node_modules/react-dom/lib/ReactDefaultBatchingStrategy.js:62:26)
      at Object.batchedUpdates (node_modules/react-dom/lib/ReactUpdates.js:97:27)
      at Object._renderNewRootComponent (node_modules/react-dom/lib/ReactMount.js:320:18)
      at Object._renderSubtreeIntoContainer (node_modules/react-dom/lib/ReactMount.js:401:32)
      at Object.render (node_modules/react-dom/lib/ReactMount.js:422:23)
      at Object.<anonymous>.it (src/App.test.js:8:48)
      at process._tickCallback (internal/process/next_tick.js:103:7)

I figured it was a problem w/ material.js, so I added it:

require('../config/jest/material.js')

it('renders without crashing', () => {
  const div = document.createElement('div')
  ReactDOM.render(<App />, div)
})

This, however, is throwing a diff't error:

TypeError: window.matchMedia is not a function

      at MaterialLayout.Object.<anonymous>.MaterialLayout.init (config/jest/material.js:3466:43)
      at new MaterialLayout (config/jest/material.js:3143:10)
      at upgradeElementInternal (config/jest/material.js:218:26)
      at Object.upgradeElementsInternal [as upgradeElements] (config/jest/material.js:265:11)
      at MDLComponent.componentDidMount (node_modules/react-mdl/lib/utils/MDLComponent.js:32:41)
      at node_modules/react-dom/lib/ReactCompositeComponent.js:265:25
      at measureLifeCyclePerf (node_modules/react-dom/lib/ReactCompositeComponent.js:75:12)
      at node_modules/react-dom/lib/ReactCompositeComponent.js:264:11
      at CallbackQueue.notifyAll (node_modules/react-dom/lib/CallbackQueue.js:76:22)
      at ReactReconcileTransaction.close (node_modules/react-dom/lib/ReactReconcileTransaction.js:80:26)
      at ReactReconcileTransaction.closeAll (node_modules/react-dom/lib/Transaction.js:206:25)
      at ReactReconcileTransaction.perform (node_modules/react-dom/lib/Transaction.js:153:16)
      at batchedMountComponentIntoNode (node_modules/react-dom/lib/ReactMount.js:126:15)
      at ReactDefaultBatchingStrategyTransaction.perform (node_modules/react-dom/lib/Transaction.js:140:20)
      at Object.batchedUpdates (node_modules/react-dom/lib/ReactDefaultBatchingStrategy.js:62:26)
      at Object.batchedUpdates (node_modules/react-dom/lib/ReactUpdates.js:97:27)
      at Object._renderNewRootComponent (node_modules/react-dom/lib/ReactMount.js:320:18)
      at Object._renderSubtreeIntoContainer (node_modules/react-dom/lib/ReactMount.js:401:32)
      at Object.render (node_modules/react-dom/lib/ReactMount.js:422:23)
      at Object.<anonymous>.it (src/App.test.js:8:48)

Before I start pulling stuff out of material.js, I wanted to check-in here and see if there was an established solution to this problem.

What's recommended way of testing w/ Jest?

kradio3 commented 7 years ago

@brandonmp Try to use enzyme https://github.com/airbnb/enzyme

import React from 'react'
import {shallow} from 'enzyme'
import App from 'your-components/App'

it('renders without crashing', () => {
  const wrapper = shallow (<App/>)
  console.log(wrapper)
})
brandonmp commented 7 years ago

thanks @kradio3 . enzyme coupled with this project seems to make jest snapshot tests work fine.

full example:

import React from 'react'
import MyThing from './index.js'
import 'react-mdl/extra/material.js'
import 'react-mdl/extra/material.css'
import { shallow } from 'enzyme'
import toJson from 'enzyme-to-json'

it('renders correctly', () => {
  const tree = shallow(
    <MyThing
          myProp={5}
    />
  )
  expect(toJson(tree)).toMatchSnapshot()
})