react-select: Simulate 'change' doesn't work for select

Hi, i’m adding tests to my pagination component based on Select

PageSizeSelector.js

class PageSizeSelector extends PureComponent {
    ..
    render() {
        const {pageSize} = this.props;
        return <Select
            options={this.pageSizeOptions}
            value={pageSize}
            onChange={(option) => this.pageSizeChangeFunc(option.value)()}
            clearable={false}
        />
    }
}

PageSizeSelector.test.js

import {mount} from 'enzyme'
...
it('changing pageSize', () => {
        let size = 0;
        const onPageSizeChanged = (pageSize) => size = pageSize;

        const wrapper = mount(
            <PageSizeSelector
                pageSize={10}
                onPageSizeChanged={onPageSizeChanged}
            />
        );

        wrapper.find('Select').simulate('change', {target: {value: 50}});
        expect(size).to.eql(50);
    })

onPageSizeChanged isn’t called. If replace simulate line with

   wrapper.find('Select').find('input').simulate('change', {target: {value: 50}});

get exception

- TypeError: str.replace is not a function
        at stripDiacritics (node_modules/react-select/lib/utils/stripDiacritics.js:7:13)
        at filterOptions (node_modules/react-select/lib/utils/defaultFilterOptions.js:13:50)
        at filterOptions (node_modules/react-select/lib/Select.js:992:11)
        at render (node_modules/react-select/lib/Select.js:1116:45)
        at node_modules/react/lib/ReactCompositeComponent.js:793:21
        at measureLifeCyclePerf (node_modules/react/lib/ReactCompositeComponent.js:74:12)

Using react-select@^1.0.0-rc.2 Looked at https://github.com/airbnb/enzyme/issues/400 as well Thanks

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Reactions: 27
  • Comments: 18 (1 by maintainers)

Most upvoted comments

+10000000000000000 🎱

I answered the question using testing-library, easily adaptable to enzyme. For me, the Select is embedded in a component, but this still works, as long as you can pick the right input value.

https://stackoverflow.com/a/57699061/141552

Basically pretend to be a screen reader.

Using testing-library and v2.0

Trying to avoid using anything very specific like classNamePrefix or hacking into the way the component operates by looking for the onChange prop or whatever.

const callback = jest.fn();
const { container, getByText} = render(<Select ... onChange={callback} />);

Now we basically pretend to be a screen reader and focus, and press the down arrow.

fireEvent.focus(container.querySelector('input'));
fireEvent.keyDown(container.querySelector('input'), { key: 'ArrowDown', code: 40 });

And now click on the value you want

fireEvent.click(getByText('Option Two'));

And assert.

expect(callback).toHaveBeenCalledWith({ value: 'two', label: 'Option Two'});

The following should:

  1. Find the Select component in your wrapper.
  2. Get its instance.
  3. Set the value to { label: "...", value: 50 }
wrapper.find('Select').instance().selectOption({ label: "...", value: 50 });

If you can you should use the original options from your options array for tests.

@nbotalov hey, went across the same problem… Only solution I found was to simulate a selection through key-down events:

wrapper.find('.Select-control').simulate('keyDown', { keyCode: 40 }); // you can use 'input' instead of '.Select-control'
wrapper.find('.Select-control').simulate('keyDown', { keyCode: 13 });
expect(size).to.eql('your first value in the list')

Using react-select version 3.1.1 still its not working. Any plan to resolve this issue sooner?

The react-testing-library solution has been extracted into a helper package: https://github.com/romgain/react-select-event