janitheshan
janitheshan

Reputation: 325

Using Enzyme with Jest to test Material-UI Select control

I'm having an issue with testing Material-UI select option. Here I have tried to test all the options are loaded in the control. But when I put a console log debug it displays nothing on the options elements.

Also, I have noted that the menu items are rendered at the bottom of the page for Material-UI. Is there a specific way to get those? Below is the code that I have tried,

ColorSelect.jsx

    import React from 'react';
    import { FormControl, MenuItem, Avatar, TextField } from '@material-ui/core';
    import styled from "styled-components";

function ColorSelect(props) {
    return (
            <FormControl variant="outlined">
                <TextField
                    id="color-id-input"
                    select
                    value={props.color}
                    label={props.color == "" ? "Color" : ""}
                    InputLabelProps={{ shrink: false }}
                    variant="outlined"
                    error={props.error}
                    helperText={props.helpertext}
                >
                    <MenuItem style={{ fontSize: "13px" }} value="">
                        <em>None</em>
                    </MenuItem>
                    {
                        props.colors.map(color => (
                            <MenuItem key={"ColorNewLineMenuItem_" + color.colorCode} style={{ fontSize: "13px" }} value={color.colorCode}>
                                <div>
                                    <Avatar key={"ColorNewLineAvatar_" + color.colorCode} src={color.imageSrc} />
                                    <div>{color.name}</div>
                                </div>
                            </MenuItem>
                        ))
                    }
                </TextField>
            </FormControl>
        )
}

export default ColorSelect;

ColorSelect.test.js

import * as React from 'react';
import MockProvider from '../../mockProvider';
import * as data from '../../data/poData.json';
import { act } from '@testing-library/react';
import { mount } from "enzyme";

import ColorSelect from '../../../components/order/ColorSelect';

test("check colors dropdown loads correctly", async () => {

     wrapper = mount(<MockProvider><ColorSelect color="" colors={data.products[0].colors} /> 
               </MockProvider>);

     await act(async () => {
            wrapper.find({ 'id': "color-id-input" }).last().simulate("click")
        });

     wrapper.update();

     console.log(wrapper.debug()) // Can't see the menu items
}

mockProvider.js

import configureMockStore from 'redux-mock-store';
import thunk from 'redux-thunk';
import { Provider } from 'react-redux';

export default function MockProvider(props) {
    const mockStore = configureMockStore([thunk]);
    const store = mockStore({order: { status: 'SUCCEEDED', selectedPo: props.data, seletedProductIds: [], seletedLineItems: []}});
    return <Provider store={store}>{props.children}</Provider>;
}

and my poData.json is like below,

{
    "id": "612a6a796cd84300df2f3263",
    "products": [
        {
            "poProductID": "612a6ac9bd6c2079cdaae9f1",
            "name": "AAAAA",
            "colors": [
                {
                    "colorCode": "1",
                    "name": "Pearl",
                    "imageSrc": "library/media-assets/2001/3001/3003.jpg"
                },
                {
                    "colorCode": "2",
                    "name": "Red",
                    "imageSrc": "/library/media-assets/2001/3009/3009.jpg"
                }
            ]
        }
    ]
}

This is what the log shows,

test debug test debug

Upvotes: 1

Views: 2262

Answers (2)

diedu
diedu

Reputation: 20775

If you want to stick to enzyme you'll have to be a little more specific

first, select the button adding the role to the find call

const button = wrapper.find({ id: "color-id-input", role: "button" });

and then simulate the mousedown event sending the button:0 in the event object

button.simulate("mousedown", {button: 0});

this is how I have it and I can see the items when debugging the wrapper

test("check colors dropdown loads correctly", async () => {
  const wrapper = mount(
    <ColorSelect color="" colors={data.products[0].colors} />
  );

  const button = wrapper.find({ id: "color-id-input", role: "button" });
  button.simulate("mousedown", { button: 0 });

  wrapper.update();
  console.log(wrapper.debug()); // should see items
});

You'd want to switch to react testing library, enzyme is kind of a hassle when testing third-party libs, sometimes you need to know the implementation details (as in this case, sending button:0)

Upvotes: 2

Oluwafemi Sule
Oluwafemi Sule

Reputation: 38922

You seem to be mixing and matching react-testing-library with enzyme. I recommend sticking with one of both.

That said, you can write the tests for your control with react-testing-library like so:

import { act, render, fireEvent, prettyDOM
} from '@testing-library/react';
//... other imports

test("check colors dropdown loads correctly", async () => {
  const wrapper = render(<ColorSelect color="" colors={data.products[0].colors}/>);

  await act(async () => {
    fireEvent.mouseDown(wrapper.getByRole("button"));
  });
  
  const options = await wrapper.getAllByRole('option');

  options.forEach(x => console.log(prettyDOM(x)));

});

There are testing examples for Select control in material-ui which you can follow as a guideline.

Upvotes: 2

Related Questions