Material-ui: Problems testings material-ui components with Jest and snapshots

Created on 10 May 2017  ·  11Comments  ·  Source: mui-org/material-ui

Problem description

Trying to test my app with Jest & snapshots it's failing because some attributes from some html elements rendered by Material-ui components get different values on each test.
I've asked in Stackoverflow without success.

Isn't it the best way to run some kind of tests?

Link to minimal working code that reproduces the issue

Taking for example code from material-ui docs (render a select field with multiple values):

import React, { Component } from 'react'
import SelectField from 'material-ui/SelectField'
import MenuItem from 'material-ui/MenuItem'

const names = [
  'Oliver Hansen',
  'Van Henry',
  'April Tucker',
  'Ralph Hubbard',
  'Omar Alexander',
  'Carlos Abbott',
  'Miriam Wagner',
  'Bradley Wilkerson',
  'Virginia Andrews',
  'Kelly Snyder'
]

/**
 * `SelectField` can handle multiple selections. It is enabled with the `multiple` property.
 */
export default class SelectFieldExampleMultiSelect extends Component {
  state = {
    values: []
  };

  handleChange = (event, index, values) => this.setState({ values })

  menuItems(values) {
    return names.map((name) => (
      <MenuItem
        key={name}
        insetChildren={true}
        checked={values && values.includes(name)}
        value={name}
        primaryText={name}
      />
    ))
  }

  render() {
    const { values } = this.state
    return (
      <SelectField
        multiple={true}
        hintText='Select a name'
        value={values}
        onChange={this.handleChange}
      >
        {this.menuItems(values)}
      </SelectField>
    )
  }
}

This is my test:

import React from 'react'
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider'
import { setFilterItems } from 'containers/MaterialsView/actions'
import renderer from 'react-test-renderer'
import Component from '../SelectFieldExampleMultiSelect'


describe('<FilterSelect />', () => {
  it('renders correctly', () => {
    const props = {
      items: [{ value: 1, primaryText: 'test' }],
      floatingLabelText: 'Label text',
      values: [],
      filterType: 'License'
    }
    const tree = renderer.create(
      <MuiThemeProvider>
        <Component />
      </MuiThemeProvider>).toJSON()
    expect(tree).toMatchSnapshot()
  })
})

However first time I run the test (no snapshots) it goes ok, but next times not (it's just an id attribute, and with some other components, an htmlFor attribute):

➜  node_modules/.bin/jest app/components/Filters/tests/SelectFieldExampleMultiSelect.test.js -u
 PASS  app/components/Filters/tests/SelectFieldExampleMultiSelect.test.js
  <FilterSelect />
    ✓ renders correctly (54ms)

Snapshot Summary
 › 1 snapshot updated in 1 test suite.

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   1 updated, 1 total
Time:        1.727s
Ran all test suites matching "app/components/Filters/tests/SelectFieldExampleMultiSelect.test.js".



➜  node_modules/.bin/jest app/components/Filters/tests/SelectFieldExampleMultiSelect.test.js   
 FAIL  app/components/Filters/tests/SelectFieldExampleMultiSelect.test.js
  ● <FilterSelect /> › renders correctly

    expect(value).toMatchSnapshot()

    Received value does not match stored snapshot 1.

    - Snapshot
    + Received

    @@ -28,11 +28,11 @@
         }>
         Select a name
       </div>
       <div
         className={undefined}
    -    id="undefined-Selectaname-undefined-45429"
    +    id="undefined-Selectaname-undefined-64546"
         onBlur={[Function]}
         onChange={[Function]}
         onFocus={[Function]}
         style={
           Object {

      at Object.<anonymous> (app/components/Filters/tests/SelectFieldExampleMultiSelect.test.js:20:18)
      at process._tickCallback (node.js:377:9)

  <FilterSelect />
    ✕ renders correctly (57ms)

Snapshot Summary
 › 1 snapshot test failed in 1 test suite. Inspect your code changes or re-run with `-u` to update them.

Test Suites: 1 failed, 1 total
Tests:       1 failed, 1 total
Snapshots:   1 failed, 1 total
Time:        1.693s
Ran all test suites matching "app/components/Filters/tests/SelectFieldExampleMultiSelect.test.js".

Versions

  • Material-UI: 17.1 and 18.0
  • React: 15.4.2
  • Browser:
bug 🐛 TextField v0.x

Most helpful comment

@mbaranovski Upgrade to v1-beta, we have removed the Math.random() logic.

All 11 comments

Thanks!
Seems like id should be required?

By the way... for some of my tests I had to mock tooltip:
jest.mock('material-ui/internal/Tooltip')

As raised by @kireerik, you can use the id property to get a predictable id.

Also, we TextField has been migrated to the next branch, that should no longer be an issue.

Hi @oliviertassinari , I think it's still an issue. Each test rerun generates new id with Math.random() here. Not possible to test components using snapshots.

@mbaranovski Upgrade to v1-beta, we have removed the Math.random() logic.

Thank you

For projects which are still dependent on older versions of material-ui should jest snapshot tests be recommended for testing....

I noticed a bunch of classes changing in snapshots using [email protected], even though I didn't change the JSX or styles. This might still be an issue.

@bishwenduk029 As a workaround you can use shallow rendering. I'm using react-test-library which doesn't support it, so unfortunately I'm still stuck.

Changing classes in snapshots are still an issue in "@material-ui/core": "1.3.1"?

@zamber Please don't comment on old issue when you can find better issue describing your issue in the GitHub history, like #9492

Was this page helpful?
0 / 5 - 0 ratings