如何使用 react-testing-library 在 react-select 组件上触发更改事件?
How do I trigger the change event on a react-select component with react-testing-library?
鉴于我无法直接使用 react-testing-library
测试内部结构,我将如何着手测试使用 react-select
的组件?例如,如果我有一个基于 react-select
的值的条件渲染,它不渲染传统的 <select/>
,我仍然可以触发更改吗?
import React, { useState } from "react";
import Select from "react-select";
const options = [
{ value: "First", label: "First" },
{ value: "Second", label: "Second" },
{ value: "Third", label: "Third" },
];
function TestApp() {
const [option, setOption] = useState(null);
return (
<div>
<label htmlFor="option-select">Select Option</label>
<Select
value={option}
options={options}
onChange={option => setOption(option)}
/>
{option && <div>{option.label}</div>}
</div>
);
}
export default TestApp;
我什至不确定我应该查询什么。是隐藏输入法吗?
您可以尝试以下方法使其正常工作:
- 在 ReactSelect 组件 .react-select 输入元素上触发焦点事件。
- 在 .react-select__control 元素上触发 mouseDown 事件
- 点击您想要的选项元素 select
您可以添加值为 "react-select" 的 className 和 classNamePrefix 道具,以便专门 select 您正在尝试测试的组件。
PS:如果你仍然卡住了,我鼓励你看看这个对话,上面的答案是借用的 - https://spectrum.chat/react-testing-library/general/testing-react-select~5857bb70-b3b9-41a7-9991-83f782377581
我的团队在我们的项目中有一个测试实用程序,它可以让我们 select 在花费太多时间试图弄清楚如何正确执行此操作后轻松地完成一项。在此分享,希望对其他人有所帮助。
这不依赖于任何 React Select 内部结构或模拟,但确实需要您设置一个 <label>
,它有一个 for
链接到 React Select 输入。它使用标签 select 给定的选择值,就像用户在真实页面上所做的那样。
const KEY_DOWN = 40
// Select an item from a React Select dropdown given a label and
// choice label you wish to pick.
export async function selectItem(
container: HTMLElement,
label: string,
choice: string
): Promise<void> {
// Focus and enable the dropdown of options.
fireEvent.focus(getByLabelText(container, label))
fireEvent.keyDown(getByLabelText(container, label), {
keyCode: KEY_DOWN,
})
// Wait for the dropdown of options to be drawn.
await findByText(container, choice)
// Select the item we care about.
fireEvent.click(getByText(container, choice))
// Wait for your choice to be set as the input value.
await findByDisplayValue(container, choice)
}
可以这样使用:
it('selects an item', async () => {
const { container } = render(<MyComponent/>)
await selectItem(container, 'My label', 'value')
})
鉴于我无法直接使用 react-testing-library
测试内部结构,我将如何着手测试使用 react-select
的组件?例如,如果我有一个基于 react-select
的值的条件渲染,它不渲染传统的 <select/>
,我仍然可以触发更改吗?
import React, { useState } from "react";
import Select from "react-select";
const options = [
{ value: "First", label: "First" },
{ value: "Second", label: "Second" },
{ value: "Third", label: "Third" },
];
function TestApp() {
const [option, setOption] = useState(null);
return (
<div>
<label htmlFor="option-select">Select Option</label>
<Select
value={option}
options={options}
onChange={option => setOption(option)}
/>
{option && <div>{option.label}</div>}
</div>
);
}
export default TestApp;
我什至不确定我应该查询什么。是隐藏输入法吗?
您可以尝试以下方法使其正常工作:
- 在 ReactSelect 组件 .react-select 输入元素上触发焦点事件。
- 在 .react-select__control 元素上触发 mouseDown 事件
- 点击您想要的选项元素 select
您可以添加值为 "react-select" 的 className 和 classNamePrefix 道具,以便专门 select 您正在尝试测试的组件。
PS:如果你仍然卡住了,我鼓励你看看这个对话,上面的答案是借用的 - https://spectrum.chat/react-testing-library/general/testing-react-select~5857bb70-b3b9-41a7-9991-83f782377581
我的团队在我们的项目中有一个测试实用程序,它可以让我们 select 在花费太多时间试图弄清楚如何正确执行此操作后轻松地完成一项。在此分享,希望对其他人有所帮助。
这不依赖于任何 React Select 内部结构或模拟,但确实需要您设置一个 <label>
,它有一个 for
链接到 React Select 输入。它使用标签 select 给定的选择值,就像用户在真实页面上所做的那样。
const KEY_DOWN = 40
// Select an item from a React Select dropdown given a label and
// choice label you wish to pick.
export async function selectItem(
container: HTMLElement,
label: string,
choice: string
): Promise<void> {
// Focus and enable the dropdown of options.
fireEvent.focus(getByLabelText(container, label))
fireEvent.keyDown(getByLabelText(container, label), {
keyCode: KEY_DOWN,
})
// Wait for the dropdown of options to be drawn.
await findByText(container, choice)
// Select the item we care about.
fireEvent.click(getByText(container, choice))
// Wait for your choice to be set as the input value.
await findByDisplayValue(container, choice)
}
可以这样使用:
it('selects an item', async () => {
const { container } = render(<MyComponent/>)
await selectItem(container, 'My label', 'value')
})