如何通过选择数据列表来测试更改事件的触发器
How to test trigger on change event by selecting data list
如何测试用户从数据列表中选择选项的情况?我正在使用 @testing-library/user-event
.
对输入断言 onChange
回调
这是我的 React 组件:
// MyInput.js
import React from "react";
const MyInput = ({ value, list, id, onChange }) => {
return (
<label>
<strong>{id}</strong>
<div>
<input type="text" value={value} onChange={onChange} list={id} />
<datalist id={id} aria-label="datalist-items">
{list.map((item) => (
<option
key={`item-${item.id}`}
aria-label="data-list-item"
value={item.value}
/>
))}
</datalist>
</div>
</label>
);
};
export default MyInput;
这是我的失败测试
// MyInput.spec.js
import React from "react";
import { render } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import MyInput from "./MyInput";
import data from "./data.json";
describe("MyInput", () => {
it("should trigger onChange with selected option", () => {
const onChange = jest.fn();
const list = [...data.list];
const screen = render(<MyInput onChange={onChange} list={list} />);
userEvent.selectOptions(screen.getByLabelText("datalist-items"), "first");
expect(onChange).toHaveBeenCalledWith("first");
});
});
提供给组件的数据:
// data.json
{
"list": [
{ "id": 1, "value": "first" },
{ "id": 2, "value": "second" }
]
}
然而那是行不通的。测试报告失败:
expect(jest.fn()).toHaveBeenCalledWith(...expected)
Expected: "first"
Number of calls: 0
14 | userEvent.selectOptions(screen.getByLabelText("datalist-items"), "first");
> 16 | expect(onChange).toHaveBeenCalledWith("first");
17 | });
18 | });
你可以找到一个活生生的例子in this CodeSandbox。
我想模拟现实生活中的场景,用户点击输入,呈现数据列表,然后用户点击其中一个选项。我应该以某种方式针对呈现的数据列表吗?以及如何?
onChange
事件处理程序被<input type='text'>
jsx使用,所以你应该使用type(element, text, [options]) to writes text inside an <input>
or a <textarea>
. selectOptions(element, values)用于选择<select>
的指定选项或一个 <select multiple>
元素。
MyInput.jsx
:
import React from 'react';
const MyInput = ({ value, list, id, onChange }) => {
return (
<label>
<strong>{id}</strong>
<div>
<input type="text" value={value} onChange={onChange} data-testid="test" list={id} />
<datalist id={id} aria-label="datalist-items">
{list.map((item) => (
<option key={`item-${item.id}`} aria-label="data-list-item" value={item.value} />
))}
</datalist>
</div>
</label>
);
};
export default MyInput;
MyInput.spec.jsx
:
import React from 'react';
import { render } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import MyInput from './MyInput';
import data from './data.json';
describe('MyInput', () => {
it('should trigger onChange with selected option', () => {
expect.assertions(6);
let events = [];
const onChange = jest.fn().mockImplementation((e) => {
e.persist();
events.push(e);
});
const list = [...data.list];
const screen = render(<MyInput onChange={onChange} list={list} id="test" />);
userEvent.type(screen.getByTestId('test'), 'first');
expect(onChange).toBeCalledTimes(5);
events.forEach((e) => {
expect(onChange).toHaveBeenCalledWith(e);
});
});
});
测试结果:
PASS examples/65687415/MyInput.spec.jsx
MyInput
✓ should trigger onChange with selected option (44 ms)
-------------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
-------------|---------|----------|---------|---------|-------------------
All files | 100 | 100 | 100 | 100 |
MyInput.jsx | 100 | 100 | 100 | 100 |
-------------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 5.175 s
包版本:
"react": "^16.14.0",
"@testing-library/react": "^11.2.2",
"@testing-library/user-event": "^12.6.0",
如何测试用户从数据列表中选择选项的情况?我正在使用 @testing-library/user-event
.
onChange
回调
这是我的 React 组件:
// MyInput.js
import React from "react";
const MyInput = ({ value, list, id, onChange }) => {
return (
<label>
<strong>{id}</strong>
<div>
<input type="text" value={value} onChange={onChange} list={id} />
<datalist id={id} aria-label="datalist-items">
{list.map((item) => (
<option
key={`item-${item.id}`}
aria-label="data-list-item"
value={item.value}
/>
))}
</datalist>
</div>
</label>
);
};
export default MyInput;
这是我的失败测试
// MyInput.spec.js
import React from "react";
import { render } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import MyInput from "./MyInput";
import data from "./data.json";
describe("MyInput", () => {
it("should trigger onChange with selected option", () => {
const onChange = jest.fn();
const list = [...data.list];
const screen = render(<MyInput onChange={onChange} list={list} />);
userEvent.selectOptions(screen.getByLabelText("datalist-items"), "first");
expect(onChange).toHaveBeenCalledWith("first");
});
});
提供给组件的数据:
// data.json
{
"list": [
{ "id": 1, "value": "first" },
{ "id": 2, "value": "second" }
]
}
然而那是行不通的。测试报告失败:
expect(jest.fn()).toHaveBeenCalledWith(...expected)
Expected: "first"
Number of calls: 0
14 | userEvent.selectOptions(screen.getByLabelText("datalist-items"), "first");
> 16 | expect(onChange).toHaveBeenCalledWith("first");
17 | });
18 | });
你可以找到一个活生生的例子in this CodeSandbox。
我想模拟现实生活中的场景,用户点击输入,呈现数据列表,然后用户点击其中一个选项。我应该以某种方式针对呈现的数据列表吗?以及如何?
onChange
事件处理程序被<input type='text'>
jsx使用,所以你应该使用type(element, text, [options]) to writes text inside an <input>
or a <textarea>
. selectOptions(element, values)用于选择<select>
的指定选项或一个 <select multiple>
元素。
MyInput.jsx
:
import React from 'react';
const MyInput = ({ value, list, id, onChange }) => {
return (
<label>
<strong>{id}</strong>
<div>
<input type="text" value={value} onChange={onChange} data-testid="test" list={id} />
<datalist id={id} aria-label="datalist-items">
{list.map((item) => (
<option key={`item-${item.id}`} aria-label="data-list-item" value={item.value} />
))}
</datalist>
</div>
</label>
);
};
export default MyInput;
MyInput.spec.jsx
:
import React from 'react';
import { render } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import MyInput from './MyInput';
import data from './data.json';
describe('MyInput', () => {
it('should trigger onChange with selected option', () => {
expect.assertions(6);
let events = [];
const onChange = jest.fn().mockImplementation((e) => {
e.persist();
events.push(e);
});
const list = [...data.list];
const screen = render(<MyInput onChange={onChange} list={list} id="test" />);
userEvent.type(screen.getByTestId('test'), 'first');
expect(onChange).toBeCalledTimes(5);
events.forEach((e) => {
expect(onChange).toHaveBeenCalledWith(e);
});
});
});
测试结果:
PASS examples/65687415/MyInput.spec.jsx
MyInput
✓ should trigger onChange with selected option (44 ms)
-------------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
-------------|---------|----------|---------|---------|-------------------
All files | 100 | 100 | 100 | 100 |
MyInput.jsx | 100 | 100 | 100 | 100 |
-------------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 5.175 s
包版本:
"react": "^16.14.0",
"@testing-library/react": "^11.2.2",
"@testing-library/user-event": "^12.6.0",