一个简单的多选组件:
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