javascript 如何在 Jest 和 Enzyme 中验证 React props?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/50364747/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to verify React props in Jest and Enzyme?
提问by vizFlux
So I was trying to learn about testing in React and I have this: Button.jsand Button.test.js
所以我试图学习在 React 中进行测试,我有这个:Button.js和Button.test.js
The question is commented along with the code below:
该问题与以下代码一起注释:
// Button.js
import React from 'react';
import { string, bool, func } from 'prop-types';
import { StyledButton } from './styled'
const Button = ({
size,
text,
}) => (
<StyledButton
size={size}
// the test will alway fail with result:
// Expected value to be: "Join us"
// Received: undefined
// Unless I add add this line below
text={text}
>
{text} // but the text props is here. That is my current practice of passing the props to the children, am I missing anything?
</StyledButton>
);
Button.propTypes = {
size: string,
text: string,
};
Button.defaultProps = {
size: '',
text: '',
};
export default Button;
// Button.test.js
import React from 'react';
import { shallow } from 'enzyme';
import Button from '../../components/Button/Button';
describe('Component: Button', () => {
const minProps = {
text: '',
size: '',
};
it('renders a button in size of "small" with text in it', () => {
const wrapper = shallow(
<Button {...minProps} size="small" text="Join us" />
);
expect(wrapper.prop('size')).toBe('small');
expect(wrapper.prop('text')).toBe('Join us');
});
});
// StyledButton
import Button from 'antd/lib/button';
const StyledButton = styled(Button)`
&.ant-btn {
padding: 0 24px;
${({ size }) => {
if (size === 'small') {
return css`
font-size: 14px;
line-height: 32px;
`;
}
return null;
}};
`;
export { StyledButton };
Does anyone know why the test will not pass unless I pass the props to the StyledButton?
有谁知道为什么除非我将道具传递给 ,否则测试不会通过StyledButton?
回答by Shubham Khatri
You need to find the StyledButtonin the Buttoncomponent before asserting the props
在断言道具之前,您需要StyledButton在Button组件中找到
// Button.test.js
import React from 'react';
import { shallow } from 'enzyme';
import Button from '../../components/Button/Button';
import { StyledButton } from './styled'
describe('Component: Button', () => {
const minProps = {
text: '',
size: '',
};
it('renders a button in size of "small" with text in it', () => {
const wrapper = shallow(
<Button {...minProps} size="small" text="Join us" />
);
expect(wrapper.find(StyledButton).prop('size')).toBe('small');
expect(wrapper.find(StyledButton).prop('text')).toBe('Join us');
});
});
回答by Jason Rice
I realize this post is a bit old but there's a much better way to test for expected prop types and their values.
我意识到这篇文章有点旧,但有更好的方法来测试预期的道具类型及其值。
Here's what I have and it works fine:
这是我所拥有的,它运行良好:
Accordion.js
手风琴.js
import React from "react";
import PropTypes from "prop-types";
import { Icon } from "../Icon";
import styled from "styled-components";
const AccordionContainer = styled.div`
display: flex;
flex-direction: column;
flex: 1;
justify-content: ${props => props.justifyContent};
background-color: ${props => props.theme.color[props.color]};
${props => props.theme.fontSize(14)};
`;
const ChildrenContainer = styled.div`
display: flex;
flex-direction: column;
`;
const LabelWrapper = styled.div`
padding: 10px;
`;
/**
* Accordion is nearly a Higher Order Component (HOC) in the fact that it encapsulates an Icon and when that
* Icon is clicked an onClick callback provided should toggle the closed state.
*/
export class Accordion extends React.Component {
constructor(props) {
super(props);
this.state = {
closed: props.closed
};
}
render() {
let {
props: {
children,
hasIcon,
iconColor,
iconFlexDirection,
iconExpand,
iconName,
iconSize,
label,
color,
justifyContent
},
state: { closed }
} = this;
return (
<AccordionContainer color={color} justifyContent={justifyContent}>
<div onClick={() => this.setState({ closed: !closed })}>
{hasIcon ? (
<>
<LabelWrapper>
<Icon
fontSize={iconSize}
name={iconName}
color={iconColor}
flexDirection={iconFlexDirection}
expand={iconExpand}
/>
</LabelWrapper>
{!closed && <ChildrenContainer>{children}</ChildrenContainer>}
</>
) : (
<>
<LabelWrapper>
<div>{label}</div>
</LabelWrapper>
{!closed && <ChildrenContainer>{children}</ChildrenContainer>}
</>
)}
</div>
</AccordionContainer>
);
}
}
Accordion.propTypes = {
color: PropTypes.string,
closed: PropTypes.bool,
justifyContent: PropTypes.string,
hasIcon: PropTypes.bool,
iconName: PropTypes.string,
iconColor: PropTypes.string,
iconExpand: PropTypes.bool,
iconSize: PropTypes.number,
label: PropTypes.string
};
Accordion.defaultProps = {
closed: true,
hasIcon: false,
iconExpand: false,
justifyContent: "flex-start"
};
Accordion.spec.js
Accordion.spec.js
import React from "react";
import { shallow, mount, render } from "enzyme";
import styled, { ThemeProvider } from "styled-components";
import theme from "../../styles/theme";
import { Accordion } from "./Accordion";
import sinon from "sinon";
describe("Accordion", () => {
const AccordionJSX = (
<ThemeProvider theme={theme}>
<Accordion
iconName="home"
iconColor="#777"
iconSize={14}
hasIcon={true}
>
HELLO ACCORDION
</Accordion>
</ThemeProvider>
);
it("Should render without throwing an error", () => {
expect(shallow(
AccordionJSX
)).not.toBeNull();
});
const AccordionComponent = mount(AccordionJSX);
it("Should have a styled-components theme", () => {
expect(AccordionComponent.props().theme).not.toBeNull();
});
it('check props passed in', () => {
console.log(AccordionComponent.props().children);
expect(AccordionComponent.props().children.props).toEqual({
iconName: 'home',
iconColor: '#777',
iconSize: 14,
hasIcon: true,
children: 'HELLO ACCORDION',
closed: true,
iconExpand: false,
justifyContent: 'flex-start'
});
});
it('check state after opened', () => {
expect(AccordionComponent.props().theme).not.toBeNull();
})
});

