Search code examples
javascriptreactjsunit-testingjestjsantd

test antd <Select/> using jest


How to change option properly using react testing library or enyzme ?

    function toggleOpen(wrapper) {
        act(() => {
            wrapper.find('.ant-select-selector').simulate('mousedown');
        });
    
        act(() => {
            wrapper.update();
        });
    }

export function selectItem(wrapper, index = 0) {
    act(() => {
        wrapper.find('.ant-select-item-option').simulate('click');
    });
}

describe('Select ', () => {
    it('should be able to select an option', async () => {
        
        let wrapper;
        act(() => {
            wrapper = mount(
                <Formik initialValues={{ paymentType: 5 }} onSubmit={jest.fn()}>
                    <Select name="paymentType">
                    <Select.Option value="5">abc</Select.Option>
                    <Select.Option value="6">xyz</Select.Option>
                </Select>

                </Formik>
            );
        });

        toggleOpen(wrapper);
        selectItem(wrapper)
        
    });
});

using above unable to select an option.


Solution

  • Here's one way to test an antd Select component:

    Working Demo

    Click here for a standalone demo

    Example Code

    App.js

    import * as React from "react";
    import { Select } from "antd";
    
    const { Option } = Select;
    
    const App = () => {
      const [value, setValue] = React.useState("lucy");
    
      const handleChange = (value) => {
        setValue(value);
      };
    
      return (
        <div className="app">
          <Select
            defaultValue={value}
            style={{ width: 120 }}
            onChange={handleChange}
          >
            <Option value="jack">Jack</Option>
            <Option value="lucy">Lucy</Option>
            <Option value="disabled" disabled>
              Disabled
            </Option>
            <Option value="Yiminghe">yiminghe</Option>
          </Select>
        </div>
      );
    };
    
    export default App;
    

    Test Setup

    DevDependencies:

    setupTests.js

    import * as React from "react";
    import { JSDOM } from "jsdom";
    import { configure } from "enzyme";
    import Adapter from "@wojtekmaj/enzyme-adapter-react-17";
    import "jest-enzyme";
    
    configure({ adapter: new Adapter() });
    
    /* THE BELOW ARE ACCESSIBLE AND PREDEFINED FOR ALL *.TEST.JS FILES */
    const { document } = new JSDOM(
      "<!DOCTYPE html><body><div id='root'></div></body>"
    ).window;
    global.document = document;
    global.window = document.defaultView;
    global.HTMLElement = window.HTMLElement;
    global.HTMLAnchorElement = window.HTMLAnchorElement;
    global.React = React;
    global.requestAnimationFrame = (callback) => setTimeout(callback, 0);
    global.cancelAnimationFrame = (id) => clearTimeout(id);
    
    global.navigator = {
      userAgent: "node.js",
    };
    

    Tests

    App.test.js (you can read more about waitForAct here)

    import { mount } from "enzyme";
    import { waitForAct } from "@noshot/utils";
    import App from "./App";
    
    const wrapper = mount(<App />);
    
    describe("App", () => {
      it("updates the select input value when an option is clicked", async () => {
        // expect initial value to be "Lucy"
        expect(wrapper.find(".ant-select-selection-item")).toHaveText("Lucy");
    
        // click on select input to open dropdown
        wrapper.find(".ant-select-selector").simulate("mousedown");
    
        // wait for the dropdown to appear and expect that it has 4 options
        await waitForAct(() => {
          wrapper.update();
          expect(wrapper.find(".ant-select-item")).toHaveLength(4);
        });
    
        // select the first option ("Jack")
        wrapper.find(".ant-select-item").first().simulate("click");
    
        // wait for the select input to update with the selected option ("Jack")
        await waitForAct(() => {
          wrapper.update();
          expect(wrapper.find(".ant-select-selection-item")).toHaveText("Jack");
        });
      });
    });
    

    Result

    enter image description here