Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to test a TextField Material-UI element with React Jest?

I built up a component with React and Material-UI. I'm using React and Redux.

my index.jsx looks like this:

import React from 'react';
import { render } from 'react-dom';
import { Provider } from 'react-redux';
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
import configureStore from '../store/configureStore';
import Routes from '../routes/routes';
import '../styles/main.less';

const store = configureStore();
render(
  <Provider store={store}>
    <MuiThemeProvider>
      <Routes />
    </MuiThemeProvider>
  </Provider>,
  document.getElementById('app'),
);

My component InputSearch looks like this:

import React, { PropTypes, Component } from 'react';
import TextField from 'material-ui/TextField';

class InputSearch extends Component {
  ...

  render() {
    return (
      ...
      <TextField
        defaultValue={this.props.keyword}
        ref={(input) => { this.input = input; }}
        autoFocus
        hintText='Type a keyword'
        errorText={this.state.errorText}
        floatingLabelText='Search for keyword'
        style={styles.textField}
      />
    );
  }
}

InputSearch.propTypes = {
  keyword: PropTypes.string.isRequired,
  resetSearch: PropTypes.func.isRequired,
  searchBooks: PropTypes.func.isRequired,
  toggleResultsOpacity: PropTypes.func.isRequired,
  firstSearch: PropTypes.bool.isRequired,
};

export default InputSearch;

I'm using Airbnb Enzyme and Jest to build unit tests. My test to the InputSearch component looks like this:

import React from 'react';
import { shallow, mount } from 'enzyme';
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
import TextField from 'material-ui/TextField';
import InputSearch from '../components/InputSearch/InputSearch';

const resetSearchMock = jest.fn();
const searchBooksMock = jest.fn();
const toggleResultsOpacityMock = jest.fn();

const setup = () => {
  const props = {
    keyword: '',
    resetSearch: resetSearchMock,
    searchBooks: searchBooksMock,
    toggleResultsOpacity: toggleResultsOpacityMock,
    firstSearch: true,
  };

  const wrapper = shallow(<MuiThemeProvider><InputSearch {...props} /></MuiThemeProvider>);

  return {
    props,
    wrapper,
  };
};

describe('Initial test', () => {
  test('Shows error message when input search is empty.', () => {
    const { wrapper, props } = setup();
    expect(wrapper.find(TextField).getValue()).toEqual('');
  });
}

However, I'm getting the following error:

TypeError: wrapper.find(...).getValue is not a function

Can anyone help me reach the right way to check the value of the Material UI TextField, please?

like image 866
Pablo Darde Avatar asked Apr 09 '17 18:04

Pablo Darde


People also ask

How do you test material UI components?

This is how MUI components are tested internally. A library that has a first-class API for this approach is @testing-library/react . For example, when rendering a TextField your test should not need to query for the specific MUI instance of the TextField but rather for the input , or [role="textbox"] .

How do I get the value of TextField material UI react?

To get data from the React Material UI TextField component, we can get the input value from the onChange function. In the function, we can get the input value from the e. target. value property and set that as the value of a state.

Can you test react with Jest?

Jest is a JavaScript testing framework that allows developers to run tests on JavaScript and TypeScript code and can be easily integrated with React JS. Open the package. json, and you will find that when you use create-react-app for creating a react project, it has default support for jest and react testing library.


1 Answers

I have been writing test for few days using mocha, enzyme and chai. The problem that comes with testing material-ui is these are inturn react component so they cannot be tested as you test regular html elements.

You can find out what property change by printing the whole component, like

console.log(wrapper.find('TextField').debug());

This will print the whole element for you, you can notice that the TestField has value prop which is what you are suppose to check because this prop is what decided the value in the TextField

So the code will go like this:

describe('Initial test', () => {
  test('Shows error message when input search is empty.', () => {
    const { wrapper, props } = setup();
    expect(wrapper.find(TextField).props().value).to.equal('');
  });
}

This is how I have been testing the TextField component.

Hope you find it helpful.

like image 179
Farhaan Bukhsh Avatar answered Sep 29 '22 08:09

Farhaan Bukhsh