我想检查单击按钮后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)
如何测试属性?
最佳答案
通过验证道具来检查属性是可以的。模拟点击就可以了。
测试失败的唯一原因是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)
在https://medium.com/@Yohanna/difference-between-enzymes-rendering-methods-f82108f49084上了解有关shallow vs mount
差异的更多信息
另一种方法是使用.dive()
这样
wrapper.dive().find(...)
甚至在初始化时:
const wrapper = shallow(...).dive();
最后,您可能只导出两个版本:基本版本(并针对该版本编写测试)并包装为
styled-components
主题。需要对代码稍作更改。而且,每次您添加更多的HOC包装器时,不喜欢上述测试的方法都不需要更新(例如将组件包装到styled-components
中,然后连接到redux
并最终添加withRouter
-测试仍将以这种方式工作)。但是从另一方面来说,这种方法不会测试您的组件,因为它实际上是集成的,因此我不确定这种方法是否更好。