我想检查单击按钮后 aria-expanded
是否发生变化。这是我的组件
import React, { useState, useRef } from 'react';
import styled from 'styled-components';
import { ArrowTemplate } from './ArrowTemplate';
import { colors } from '../../utils/css';
import { Text } from '../Text';
const Accordion = ({
rtl, content, color, title, className,
}) => {
const element = useRef(null);
const [isAccordionExpanded, setIsAccordionExpanded] = useState(false);
const toggleAccordion = () => {
setIsAccordionExpanded(!isAccordionExpanded);
};
const height = element.current ? element.current.scrollHeight : '0';
return (
<div className={`accordion-section ${className}`}>
<button className={'accordion-btn'} onClick={toggleAccordion}>
<p className={'accordion-title'}>
<Text isRtl={rtl}>{title}</Text>
</p>
<ArrowTemplate
direction={isAccordionExpanded ? 'up' : 'down'}
onClick={toggleAccordion}
rtl={rtl}
color={color}
/>
</button>
<AccordionContent
className={'accordion-content'}
height={height}
isAccordionExpanded={isAccordionExpanded}
ref={element}
aria-expanded={isAccordionExpanded}
>
<div className={'accordion-text'}>
<Text isRtl={rtl}>{content}</Text>
</div>
</AccordionContent>
</div>
);
};
export const StyledAccordion = styled(Accordion)`
font-family: "Open Sans", sans-serif;
text-align: ${({ rtl }) => (rtl ? 'right' : 'left')};
display: flex;
flex-direction: column;
.accordion-btn {
position: relative;
width: 100%;
background-color: ${colors.LG_GREY_4};
color: ${colors.LG_GREY_5};
cursor: pointer;
padding: 40px 18px;
display: flex;
align-items: center;
border: none;
outline: none;
:hover,
:focus,
:active {
background-color: ${colors.LG_GREY_6};
}
.accordion-title {
${({ rtl }) => (rtl ? 'right: 50px;' : 'left: 50px;')};
position: absolute;
font-weight: 600;
font-size: 14px;
}
}
`;
export const AccordionContent = styled.div`
max-height: ${({ isAccordionExpanded, height }) => (isAccordionExpanded ? height : '0')}px;
overflow: hidden;
background: ${colors.LG_GREY_7};
transition: max-height 0.7s;
.accordion-text {
font-weight: 400;
font-size: 14px;
padding: 18px;
}
`;
这是我的测试
import React from 'react';
import { shallow, configure } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
import { StyledAccordion, AccordionContent } from '../Accordion';
configure({ adapter: new Adapter() });
describe('<StyledAccordion/>',
() => {
let wrapper;
beforeEach(() => {
wrapper = shallow(<StyledAccordion/>);
});
it('should match the snapshot', () => {
expect(wrapper).toMatchSnapshot();
});
it('should originally have aria-expanded set to false', () => {
expect(wrapper.find(AccordionContent).props()['aria-expanded']).toBe(false);
});
it('should set aria-expanded to true onClick', () => {
wrapper.find('.accordion-btn').simulate('click');
expect(wrapper.find(AccordionContent).props()['aria-expanded']).toBe(true);
});
});
这是我在控制台中得到的内容
FAIL src/components/Accordion/test/Accordion.test.js (21.497s)
● <StyledAccordion/> › should originally have aria-expanded set to false
Method “props” is meant to be run on 1 node. 0 found instead.
16 | });
17 | it('should originally have aria-expanded set to false', () => {
> 18 | expect(wrapper.find(AccordionContent).props()['aria-expanded']).toBe(false);
| ^
19 | });
20 | it('should set aria-expanded to true onClick', () => {
21 | wrapper.find('.accordion-btn').simulate('click');
at ShallowWrapper.single (node_modules/enzyme/src/ShallowWrapper.js:1636:13)
at ShallowWrapper.single [as props] (node_modules/enzyme/src/ShallowWrapper.js:1160:17)
at Object.props (src/components/Accordion/test/Accordion.test.js:18:45)
● <StyledAccordion/> › should set aria-expanded to true onClick
Method “simulate” is meant to be run on 1 node. 0 found instead.
19 | });
20 | it('should set aria-expanded to true onClick', () => {
> 21 | wrapper.find('.accordion-btn').simulate('click');
| ^
22 | expect(wrapper.find(AccordionContent).props()['aria-expanded']).toBe(true);
23 | });
24 | });
at ShallowWrapper.single (node_modules/enzyme/src/ShallowWrapper.js:1636:13)
at ShallowWrapper.single [as simulate] (node_modules/enzyme/src/ShallowWrapper.js:1118:17)
at Object.simulate (src/components/Accordion/test/Accordion.test.js:21:38)
如何测试属性?
最佳答案
通过验证 props 来检查属性是可以的。模拟点击就可以了。
测试失败的唯一原因是 shallow()
在幕后工作。
您可以通过检查 wrapper.debug()
自行找出答案返回(例如添加 console.log(wrapper.debug())
)
您会看到类似 <StyledComponentConsumer><Component ...></StyledComponentConsumer>
的内容。所以原因是shallow()
不渲染嵌套组件。比如说,如果没有styled-components
你试图 shallow(<Accordion />).find('span')
(假设 <Text>
应呈现为 <span>
)您也永远不会发现这一点。
第一个解决方案可能正在使用mount()
而不是shallow()
(您甚至不需要更改测试)。但我想走不同的路(不过只是一个意见:https://hackernoon.com/why-i-always-use-shallow-rendering-a3a50da60942)
了解更多关于shallow vs mount
的信息差异在https://medium.com/@Yohanna/difference-between-enzymes-rendering-methods-f82108f49084
另一种方法是使用 .dive()
喜欢
wrapper.dive().find(...)
甚至在初始化时:
const wrapper = shallow(...).dive();
最后您可以导出两个版本:基础版本(并针对该版本编写测试)并包装到 styled-components
中。主题化。需要对代码进行更多更改。并且每次添加更多 HOC 包装器时,不喜欢上述测试的方法都不需要更新(例如将组件包装到 styled-components
,然后连接到 redux
,最后添加 withRouter
- 测试仍然会以这种方式工作)。但从另一方面来看,这种方法不会测试您的组件,因为它实际上是集成的,所以我不确定这种方法是否更好。
关于javascript - 使用 Jest/Enzyme 检查咏叹调,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57774316/