bkula
bkula

Reputation: 559

Enzyme's simulate() not changing output for onChange event

I have this component and some tests:

import React from 'react'; import PropTypes from 'prop-types';

function SubList (props) {
    var subways = ['', '1', '2', '3', '4', '5', '6', 
    'S', 'A', 'C', 'E', 'B', 'D', 'F', 'M', 'N', 'Q', 'R', 'L', 'G']
    return (
        <select onChange={props.onSubSelect}>
            {
                subways.map(subway =>
                    <option key={subway}>
                        {subway}
                    </option>
                )
            }
        </select>
    )
}
SubList.PropTypes = {
    onSubSelect: React.PropTypes.func.isRequired
};

export default SubList;

Tests:

import React from 'react';
import {shallow} from 'enzyme';
import SubList from '../components/SubList';

let subSelectFn, wrapper;

beforeEach(() => {
    subSelectFn = jest.fn();
    wrapper = shallow(<SubList onSubSelect={subSelectFn}/>);
});

afterEach(() => {
    subSelectFn.mockReset();
});

it('should render a list of subways as an dropdown menu', () => {
    expect(wrapper.find('option').length).toBe(20);
});

it('should display the subway line in each `<option>` element', 
() => {
    const secondElement = wrapper.find('option').at(1);
    expect(secondElement.contains('1')).toEqual(true);
});

it('should call `props.onSubSelect` when an `option` is clicked', 
() => {
    // Expect that no calls have been made yet
    expect(subSelectFn.mock.calls.length).toEqual(0);

    // Click the <option>
    wrapper.find('select').simulate('click');

    // Check that the function has been called
    expect(subSelectFn.mock.calls.length).toEqual(1);

    // Check that the function was called with the right arguments
    expect(subSelectFn.mock.calls[0][0]).toEqual('1');
});

The test last test keeps failing, and I'm pretty sure it's expect(subSelectFn.mock.calls.length).toEqual(1); specifically. I'm also pretty sure that means that what is failing Enzyme's simulate(). I've tried passing it the second ('option').at('1') because ('option').first() is blank and also ('select') as you see here. I've seen simulate()'s common gotchas in the docs and not sure if one of those is what's happening to me?

The message I'm getting in my console for the failed test is

● should call 'props.onSubSelect' when an 'option' is clicked

expect(received).toEqual(expected)

Expected value to equal:
  1
Received:
  0

Upvotes: 0

Views: 5635

Answers (3)

Roman
Roman

Reputation: 21765

I found the following variant working:

wrapper.find('select').simulate('change', { subway: '1' });

Upvotes: 0

Hom Bahrani
Hom Bahrani

Reputation: 3532

@patrick is correct, I got confused by this and initially used a different event type, but the correct one is change.

wrapper.find('select').simulate('change', { target: { value: '1' } });

In the component ensure that you set a value attribute to each option

<select className="form-control" id="select-box" name="select-box" 
        onChange={(e) => this.handleChange(e.target.value)}>
          <option>Select an option</option>
          {
            this.props.options.map((o, index) => {
              return (
                <option key={index} value={o}>
                  {o}
                </option>
              );
            })
          }
</select>

Upvotes: 2

patrick
patrick

Reputation: 10273

You're using 'click' for your simulate. Instead, try this:

wrapper.find('select').simulate('change', 1);

Upvotes: 3

Related Questions