大家好,我正在尝试测试一个用Material-UI创建的Slider组件,但是我无法将我的测试转到pass。我想使用fireEvent
和@testing-library/react
来测试值的变化。我一直在关注这篇文章,以正确地查询DOM,我无法获得正确的DOM节点。
先谢谢你。
<Slider />
元件
// @format
// @flow
import * as React from "react";
import styled from "styled-components";
import { Slider as MaterialUISlider } from "@material-ui/core";
import { withStyles, makeStyles } from "@material-ui/core/styles";
import { priceRange } from "../../../domain/Search/PriceRange/priceRange";
const Wrapper = styled.div`
width: 93%;
display: inline-block;
margin-left: 0.5em;
margin-right: 0.5em;
margin-bottom: 0.5em;
`;
// ommited code pertaining props and styles for simplicity
function Slider(props: SliderProps) {
const initialState = [1, 100];
const [value, setValue] = React.useState(initialState);
function onHandleChangeCommitted(e, latestValue) {
e.preventDefault();
const { onUpdate } = props;
const newPriceRange = priceRange(latestValue);
onUpdate(newPriceRange);
}
function onHandleChange(e, newValue) {
e.preventDefault();
setValue(newValue);
}
return (
<Wrapper
aria-label="range-slider"
>
<SliderWithStyles
aria-labelledby="range-slider"
defaultValue={initialState}
// getAriaLabel={index =>
// index === 0 ? "Minimum Price" : "Maximum Price"
// }
getAriaValueText={valueText}
onChange={onHandleChange}
onChangeCommitted={onHandleChangeCommitted}
valueLabelDisplay="auto"
value={value}
/>
</Wrapper>
);
}
export default Slider;
Slider.test.js
// @flow
import React from "react";
import { cleanup,
render,
getAllByAltText,
fireEvent,
waitForElement } from "@testing-library/react";
import "@testing-library/jest-dom/extend-expect";
import Slider from "../Slider";
afterEach(cleanup);
describe("<Slider /> specs", () => {
// [NOTE]: Works, but maybe a better way to do it ?
xdescribe("<Slider /> component aria-label", () => {
it("renders without crashing", () => {
const { container } = render(<Slider />);
expect(container.firstChild).toBeInTheDocument();
});
});
// [ASK]: How to test the event handlers with fireEvent.
describe("<Slider /> props", () => {
it("display a initial min value of '1'", () => {
const renderResult = render(<Slider />);
// TODO
});
it("display a initial max value of '100'", () => {
const renderResult = render(<Slider />);
// TODO
});
xit("display to values via the onHandleChangeCommitted event when dragging stop", () => {
const renderResult = render(<Slider />);
console.log(renderResult)
// fireEvent.change(renderResult.getByText("1"))
// expect(onChange).toHaveBeenCalled(0);
});
// [NOTE]: Does not work, returns undefined
xit("display to values via the onHandleChange event when dragging stop", () => {
const renderResult = render(<Slider />);
console.log(renderResult.container);
const spanNodeWithAriaAttribute = renderResult.container.firstChild.getElementsByTagName("span")[0].getAttribute('aria-label')
expect(spanNodeWithAriaAttribute).toBe(/range-slider/)
});
});
// [ASK]: Works, but a snapshot is an overkill a better way of doing this ?
xdescribe("<Slider /> snapshot", () => {
it("renders without crashing", () => {
const { container } = render(<Slider />);
expect(container.firstChild).toMatchSnapshot();
});
});
});
5条答案
按热度按时间bogh5gae1#
经过几个小时的斗争,我能够解决我的情况下有关测试MUI滑块
这真的取决于你需要如何测试你的,在我的情况下,我必须检查一个标签文本内容是否已经改变后,点击一个标记使用
marks
滑块道具。"问题"
1)
slider
组件根据元素getBoundingClientRect
和MouseEvent
计算返回值2)如何查询
slider
并引发事件。3)JSDOM对阅读元素实际高度和宽度的限制导致了问题1
解决方案
1)mock
getBoundingClientRect
还应该修复第3个问题2)将测试ID添加到滑块并使用
fireEvent.mouseDown(contaner, {....})
70gysomp2#
我建议不要为自定义组件编写测试,并相信该组件适用于我们所有的情况。
阅读this article以了解更多细节。因为他们已经提到了如何为 Package
react-select
的组件编写单元测试。我采用了类似的方法,并为我的第三方滑块组件编写了一个mock。
在
setupTests.js
中:通过这个模拟,您可以简单地在测试中触发一个change事件,如下所示:
确保将正确的
testid
作为属性传递给SliderWithStyles
组件iqjalb3h3#
我把上面提到的解决方案变成了简单的(Typescript)助手
用法:
omqzjyyz4#
基于@reman_00001的答案,我为组件创建了一个文件mock。我用TypeScript编写了它,但是没有类型它应该也能正常工作。
x1月0n1x日
现在,Material UI
<Slider/>
组件的每次使用都将在测试期间呈现为一个简单的HTML<input/>
元素,使用Jest和react-testing-library
更容易处理。{...(others as any)}
是一个黑客,它让我不必担心原始组件的每一个可能的属性都被正确处理。根据你所依赖的Slider
属性,你可能需要在反结构化过程中提取额外的属性,这样你就可以正确地将它们转换成对普通<input/>
元素有意义的东西。See this page in the Material UI docs了解每一个可能的属性的信息。46scxncf5#
下面是一个简单而灵活的方法:
1.导入Mui,如下所示:
1.模拟@mui/材料库并为
Slider
指定一个函数1.监视Slider并编写自己的实现
1.呈现组件并触发change事件:
完整示例: