3

I need to unit test a callback provided to 'onChanged' event in an office-ui-fabric Dropdown (with spyOn and expect(callback).toHaveBeenCalled()). The problem is that I don't know how to trigger this event? I tried to look at the DOM but there are no html select tag that I can trigger. I also tried to change the state of the selected item (on the dropdown component) but I get an error with Jest telling me that I can only change the state of a root element (I tried with shallow, mount and dive into the dropdown component). Is there an easy way to accomplish this?

I am using Jest with Enzyme and this code:

const div = document.createElement('div');
ReactDOM.render(<Dropdown
            label='My label'
            placeHolder='My placeholder'
            options={[
                { key: 'A', text: 'Option a' },
                { key: 'B', text: 'Option b' },
            ]}
            onChanged={() => { return; }} />, div);
const dropdownContainer = div.querySelector('.ms-Dropdown') as HTMLElement;
ReactTestUtils.Simulate.click(dropdownContainer);

And it outputs this html:

<div class="ms-Dropdown-container">
    <label class="ms-Label ms-Dropdown-label root-37" id="Dropdown0-label" for="Dropdown0">My label</label>
    <div data-is-focusable="true" id="Dropdown0" tabindex="0" aria-expanded="true" role="listbox" aria-autocomplete="none" aria-live="off" aria-describedby="Dropdown0-option" class="ms-Dropdown root_f16b4a0d is-open" aria-owns="Dropdown0-list">
        <span id="Dropdown0-option" class="ms-Dropdown-title title_f16b4a0d ms-Dropdown-titleIsPlaceHolder titleIsPlaceHolder_f16b4a0d" aria-atomic="true" role="listbox" aria-readonly="true">
            <span>My placeholder</span>
        </span>
        <span class="ms-Dropdown-caretDownWrapper caretDownWrapper_f16b4a0d">
            <i data-icon-name="ChevronDown" class="ms-Dropdown-caretDown caretDown_f16b4a0d root-39" role="presentation" aria-hidden="true"></i>
        </span>
    </div>
    <span class="ms-Layer"/>
</div>

There is no ".ms-Dropdown-item"

Eric
  • 107
  • 1
  • 6

1 Answers1

0

You should be able to use querySelector with ID ms-Dropdown and then ReactTestUtils.Simulate.click. There are examples of this in the existing Dropdown unit tests:

it('issues the onChanged callback when the selected item is different', () => {
  const container = document.createElement('div');
  let dropdownRoot: HTMLElement | undefined;

  document.body.appendChild(container);

  const onChangedSpy = jasmine.createSpy('onChanged');

  try {
    ReactDOM.render(
      <Dropdown label="testgroup" defaultSelectedKey="1" onChanged={onChangedSpy} options={DEFAULT_OPTIONS} />,
      container
    );
    dropdownRoot = container.querySelector('.ms-Dropdown') as HTMLElement;

    ReactTestUtils.Simulate.click(dropdownRoot);

    const secondItemElement = document.querySelector('.ms-Dropdown-item[data-index="2"]') as HTMLElement;
    ReactTestUtils.Simulate.click(secondItemElement);
  } finally {
    expect(onChangedSpy).toHaveBeenCalledWith(DEFAULT_OPTIONS[2], 2);
  }
});

Unit test source file: https://github.com/OfficeDev/office-ui-fabric-react/blob/master/packages/office-ui-fabric-react/src/components/Dropdown/Dropdown.test.tsx

Jason Gore
  • 181
  • 4
  • 1
    I edited my question with my actual code which is pretty much the same as what you showed. – Eric Jun 28 '18 at 12:02
  • The Fabric unit tests work, however. I wonder if it's a test environment or test setup issue? Can you easily move your code under test into Fabric temporarily and see if it has the same issue with a similar unit test? – Jason Gore Jun 29 '18 at 15:40