【发布时间】:2020-06-11 04:48:00
【问题描述】:
我有以下 MenuList 组件,我想在其上测试按键事件。
组件:
import MenuItem from '@material-ui/core/MenuItem';
import MenuList from '@material-ui/core/MenuList';
import * as React from 'react';
export default function App() {
return (
<div>
<MenuList autoFocusItem={true}>
<MenuItem>option 1</MenuItem>
<MenuItem>option 2</MenuItem>
<MenuItem>option 3</MenuItem>
</MenuList>
</div>
);
}
测试:
import {
fireEvent,
render,
} from 'test-utils';
import React from 'react';
import TestMenuList from './TestMenuList';
test('that on key down press, the focus on menu list item moves down', async () => {
// Render component
const { getAllByRole, getByRole } = render(<TestMenuList />, {});
let MenuItem1 = getAllByRole('menuitem')[0];
expect(MenuItem1.classList.contains('Mui-focusVisible')).toBe(true); // assert 1
const Menu = getByRole('menu');
fireEvent.keyDown(Menu, { Key: 'ArrowDown', code: 40 });
MenuItem1 = getAllByRole('menuitem')[0];
const MenuItem2 = getAllByRole('menuitem')[1];
expect(MenuItem1.classList.contains('Mui-focusVisible')).toBe(false); // assert 2
expect(MenuItem2.classList.contains('Mui-focusVisible')).toBe(true); // assert 3
});
为了确保某个菜单项处于焦点位置,我正在检查该菜单项是否具有 Mui-focusVisible 类。因为我在MenuList 中设置了autoFocusItem={true},所以第一个菜单项应该自动添加Mui-focusVisible 类。那就是正在通过的断言语句 1。
let MenuItem1 = getAllByRole('menuitem')[0];
expect(MenuItem1.classList.contains('Mui-focusVisible')).toBe(true); // assert 1
然后我在菜单上触发了一个按键事件
const Menu = getByRole('menu');
fireEvent.keyDown(Menu, { Key: 'ArrowDown', code: 40 });
并检查Mui-focusVisible 类是否已从第一个菜单项中删除并添加到第二个菜单项中。现在,测试在断言语句 2 和 3 处失败。
MenuItem1 = getAllByRole('menuitem')[0];
const MenuItem2 = getAllByRole('menuitem')[1];
expect(MenuItem1.classList.contains('Mui-focusVisible')).toBe(false); // assert 2
expect(MenuItem2.classList.contains('Mui-focusVisible')).toBe(true); // assert 3
我为MenuItem1 和MenuItem2 记录了classList,以查看Mui-focusVisible 是否从第一个菜单项中删除并在按键事件后添加到第二个菜单项。但是Mui-focusVisible 类仍然在第一个菜单项中,而不是在第二个菜单项中。
我尝试添加await wait()。
fireEvent.keyDown(Menu, { Key: 'ArrowDown', code: 40 });
await wait();
用act(() => {})包装火灾事件,
act(() => fireEvent.keyDown(Menu, { Key: 'ArrowDown', code: 40 }));
await wait()
在第一个菜单列表项而不是菜单本身上触发按键事件。
act(() => fireEvent.keyDown(MenuItem1, { Key: 'ArrowDown', code: 40 }));
await wait()
他们都没有工作。我为这个组件创建了一个codesandbox,在这里,它似乎在 UI 中完美运行。但是测试失败了。
【问题讨论】:
标签: javascript reactjs typescript material-ui react-testing-library