1

一个简单的多选组件:

import React from 'react'

type Props = {
  onSelectedValuesChange: (value: string[]) => void
}

export default function MultiSelect({onSelectedValuesChange}: Props) {

  function onSelectOptions(event: React.ChangeEvent<HTMLSelectElement>) {
    const selectedOptions = event.target.selectedOptions;
    const selectedValues = Array.from(selectedOptions).map((it) => it.value);
    console.log("### selected values: ", selectedValues);
    onSelectedValuesChange(selectedValues);
  }


  return <select multiple data-testid="select-multiple"
                 onChange={onSelectOptions} style={{width: '100px'}}>
    <option data-testid="val1" value="1">1</option>
    <option data-testid="val2" value="2">2</option>
    <option data-testid="val3" value="3">3</option>
  </select>
};

当用户选择任何选项时,它会将选定的值发送到onSelectedValuesChange回调。

我想对其进行测试并用于@testing-library/user-event模拟用户选择选项。

const mockOnChange = jest.fn()
const {getByTestId} = render(<MultiSelect onSelectedValuesChange={mockOnChange}/>)

userEvent.selectOptions(getByTestId("select-multiple"), ["1", "3"]);

// (1) here are correct
expect((getByTestId("val1") as HTMLOptionElement).selected).toBe(true);
expect((getByTestId("val2") as HTMLOptionElement).selected).toBe(false);
expect((getByTestId("val3") as HTMLOptionElement).selected).toBe(true);

// (2) but here is failed ???
expect(mockOnChange).toHaveBeenLastCalledWith(["1", "3"]);

代码中的第 (1) 部分按预期工作,但第 (2) 部分失败。mockOnChange回调仅["1"]作为传递参数获取。

这里还有一些控制台中的消息可能有用:

    expect(jest.fn()).toHaveBeenLastCalledWith(...expected)

    Expected: ["1", "3"]
    Received
           1: ["1"]
    ->     2
              Array [
                "1",
            -   "3",
              ],

    Number of calls: 2

      18 | 
      19 |     // but here is failed ???
    > 20 |     expect(mockOnChange).toHaveBeenLastCalledWith(["1", "3"]);
         |                          ^
      21 |   });
      22 | })
      23 | 

      at Object.it (src/MultiSelect.test.tsx:20:26)

  console.log src/MultiSelect.tsx:12
    ### selected values:  [ '1' ]

  console.log src/MultiSelect.tsx:12
    ### selected values:  [ '1' ]

我们可以看到onSelectOptions已经被调用了 2 次,但参数总是['1']

我滥用什么了吗?

这是此问题的一个小而完整的演示:https ://github.com/freewind-demos/typescript-react-testing-library--user-event--multiple-select--demo

4

1 回答 1

-1

我通过更新 Jest 来修复失败的测试npm install jest@latest。看来这只是 JSDOM 的较旧捆绑版本的错误,而不是user-event.

拉取带有修复的演示请求

于 2020-06-09T00:25:02.190 回答