How to tests for material-ui components

How to tests for material-ui components

If you're reading this article. I assume you already know what material-ui is so i'll leave all the unnecessary details. For this tutorial we'll be writing tests for a material-ui form.

mui.jpg

DEPENDENCIES:

  1. react
  2. material-ui
  3. enzyme
  4. React-16-enzyme-adapter

Let's get started.

npx create-react-app mui-test

cd mui-test

npm i enzyme react-16-enzyme-adapter @material-ui/core

We just created a new react app and installed all the dependencies. Next, we'll do a little configuration for our app to work properly. Inside your src folder, open your setupTests.js and paste the following code

import { configure } from "enzyme"
import Adapter from "react-16-enzyme-adapter"

configure({ adapter: new Adapter() })

That's all the configuration we need.

Next, let's jump into our tests. Writing tests before the actual code is called Test Driven Development . We are then going to create a folder called tests. Inside our tests folder, we are going to create a Login.test.js file.

import React from 'react';
import { createShallow } from '@material-ui/core/test-utils';

// we are importing the component we are to test
import Login from '../components/auth/Login';

import Button from '@material-ui/core/Button';
import TextField from '@material-ui/core/TextField';

We imported createShallow in order to shallow render our components.

Shallow rendering lets you render a component “one level deep” and assert facts about what its render method returns, without worrying about the behavior of child components, which are not instantiated or rendered. This does not require a DOM.


describe ('<Login /> component', () => {
  let shallow;

  beforeAll (() => {
    // because we're using Jest, we use beforeAll
    shallow = createShallow ();
  });

  it ('should have a login button', () => {
    const wrapper = shallow (<Login />);
    expect (wrapper.find (Button).length).toEqual (1);
  });

  it ('should have two inputs fields', () => {
    const wrapper = shallow (<Login />);
    expect (wrapper.find (TextField).length).toEqual (2);
  });
})

From our code, we expect our Login components to have 2 input fields and a submit button. That's a basic requirement to test our code. But we're going to make our test a lot better and efficient. To do this , we're going to give our various components html attributes so we can target the directly.

describe ('<Login /> component', () => {
  let shallow;

  beforeAll (() => {
    // because we're using Jest, we use beforeAll
    shallow = createShallow ();
  });

  it ('should have a login button', () => {
    const wrapper = shallow (<Login />);

// Targeting our component using html attributes
    expect (wrapper.find ('[data-submit-btn]').length).toEqual (1);
  });
})

The above code is an example of targeting material-ui components using html attributes.

Finally, we are going to test our components to see if their value prop changes when a use starts interacting with it.

  it ('should simulate a change in the email input field', () => {
    const wrapper = shallow (<Login />);
    wrapper.find ('[data-email-field]').simulate ('change', {
      target: {
        value: 'hamsaharcourt@gmail.com',
      },

  expect (wrapper.find ('[data-email-field]').prop ('value')).toEqual (
      'hamsaharcourt@gmail.com'
    );
    });

That is all we basically to test our components. Putting all the pieces together, we have the following code

import React from 'react';
import {createShallow} from '@material-ui/core/test-utils';

import Login from '../components/auth/Login';

import Button from '@material-ui/core/Button';
import TextField from '@material-ui/core/TextField';


describe ('<Login  /> component', () => {
  let shallow;

  beforeAll (() => {
   // because we're using Jest, we use beforeAll
    shallow = createShallow ();
  });

  it ('should have a login button', () => {
    const wrapper = shallow (<Login />);
    expect (wrapper.find (Button).length).toEqual (1);
  });

  it ('should have two inputs fields', () => {
    const wrapper = shallow (<Login />);
    expect (wrapper.find (TextField).length).toEqual (2);
  });

  it ('should simulate a change in the email input field', () => {
    const wrapper = shallow (<Login />);
    wrapper.find ('[data-email-field]').simulate ('change', {
      target: {
        value: 'hamsaharcourt@gmail.com',
      },

  expect (wrapper.find ('[data-email-field]').prop ('value')).toEqual (
      'hamsaharcourt@gmail.com'
    );
    });
})

I hope you found this tutorial useful. Please I need your feedbacks in other to release better contents.

Happy coding :)