测试反应组件期间的失败案例
Failing case during testing react component
我在测试 React 组件时遇到问题。这是我的代码。
// Component textfield-input.jsx
import React, { PropTypes } from 'react'
import HelpComponent from '../../atoms/help-component'
export default function TextField(props) {
const { helpMessage, label, error, ...rest } = props
return (
<div className="text-field">
<label htmlFor={props.name} className="name-label">
{label}
{helpMessage ?
<HelpComponent message={helpMessage} /> : null
}
</label>
{props.required ? <span className="dot">*</span> : null}
<input className={`input ${error ? 'error' : ''}`} {...rest} />
{error && (<span className="error-text">{error}</span>)}
</div>
)
}
TextField.propTypes = {
name: PropTypes.string.isRequired,
label: PropTypes.string.isRequired,
helpMessage: PropTypes.string,
error: PropTypes.string,
required: PropTypes.bool,
}
这是我的 TextField 组件。
// Help Component
import React, { PropTypes } from 'react'
export default function HelpComponent(props) {
const direction = props.direction || 'right'
return (
<i
className="fa fa-question-circle"
data-toggle="tooltip"
data-placement={direction}
title={props.message}
aria-hidden="true"
/>
)
}
HelpComponent.propTypes = {
direction: PropTypes.string,
message: PropTypes.string.isRequired
}
这是我在 TextField 组件中使用的 HelpComponent。
// Test textfield-input.spec.jsx
import React from 'react'
import { shallow } from 'enzyme'
import TextField from '../../src/components/molecules/form/textfield-input'
describe('Unit: TextField component', () => {
let component
let props = {
name: 'text',
label: 'Text',
}
const COMPONENT = <TextField {...props} />
beforeEach(() => {
component = shallow(COMPONENT)
})
it('should be react component', () => {
expect(component.exists()).to.be.true
})
it('should render proper TextField', () => {
expect(component.find('.text-field').exists()).to.be.true
expect(component.find('.name-label').contains(props.label)).to.be.true
expect(component.find(`input[name="${props.name}"]`).exists()).to.be.true
})
it('should render help message', () => {
component.setProps({ helpMessage: 'help message' })
expect(component.find('.fa').exists()).to.be.true
})
})
测试规范。应测试 TextField 输入。但是 'should render help message' 案例失败了。任何其他情况都有效。
AssertionError:预期假为真。不过应该是真的。
编辑: 将 shallow 切换为 mount 后更糟。然后所有情况都失败 - 'should be react component' 例外 - 通过。
解决方法: @shota 是对的。我应该使用 mount 而不是 shallow。但是我的测试用例也是错误的。这是正确的方法。
expect(component.find('.name-label').text()).to.equal(props.label)
而不是
expect(component.find('.name-label').contains(props.label)).to.be.true
现在一切正常。
谢谢~!
您正在使用 shallow
渲染,这就是它失败的原因。当使用浅层渲染时,子组件不会被渲染,但会保留为组件。
所以在你的情况下,它不会进入子组件并测试 class 是否存在,而是测试渲染方法和原始组件中的直接节点而不渲染它们。
所以如果你也需要测试子组件,你需要full dom rendering
我在测试 React 组件时遇到问题。这是我的代码。
// Component textfield-input.jsx
import React, { PropTypes } from 'react'
import HelpComponent from '../../atoms/help-component'
export default function TextField(props) {
const { helpMessage, label, error, ...rest } = props
return (
<div className="text-field">
<label htmlFor={props.name} className="name-label">
{label}
{helpMessage ?
<HelpComponent message={helpMessage} /> : null
}
</label>
{props.required ? <span className="dot">*</span> : null}
<input className={`input ${error ? 'error' : ''}`} {...rest} />
{error && (<span className="error-text">{error}</span>)}
</div>
)
}
TextField.propTypes = {
name: PropTypes.string.isRequired,
label: PropTypes.string.isRequired,
helpMessage: PropTypes.string,
error: PropTypes.string,
required: PropTypes.bool,
}
这是我的 TextField 组件。
// Help Component
import React, { PropTypes } from 'react'
export default function HelpComponent(props) {
const direction = props.direction || 'right'
return (
<i
className="fa fa-question-circle"
data-toggle="tooltip"
data-placement={direction}
title={props.message}
aria-hidden="true"
/>
)
}
HelpComponent.propTypes = {
direction: PropTypes.string,
message: PropTypes.string.isRequired
}
这是我在 TextField 组件中使用的 HelpComponent。
// Test textfield-input.spec.jsx
import React from 'react'
import { shallow } from 'enzyme'
import TextField from '../../src/components/molecules/form/textfield-input'
describe('Unit: TextField component', () => {
let component
let props = {
name: 'text',
label: 'Text',
}
const COMPONENT = <TextField {...props} />
beforeEach(() => {
component = shallow(COMPONENT)
})
it('should be react component', () => {
expect(component.exists()).to.be.true
})
it('should render proper TextField', () => {
expect(component.find('.text-field').exists()).to.be.true
expect(component.find('.name-label').contains(props.label)).to.be.true
expect(component.find(`input[name="${props.name}"]`).exists()).to.be.true
})
it('should render help message', () => {
component.setProps({ helpMessage: 'help message' })
expect(component.find('.fa').exists()).to.be.true
})
})
测试规范。应测试 TextField 输入。但是 'should render help message' 案例失败了。任何其他情况都有效。
AssertionError:预期假为真。不过应该是真的。
编辑: 将 shallow 切换为 mount 后更糟。然后所有情况都失败 - 'should be react component' 例外 - 通过。
解决方法: @shota 是对的。我应该使用 mount 而不是 shallow。但是我的测试用例也是错误的。这是正确的方法。
expect(component.find('.name-label').text()).to.equal(props.label)
而不是
expect(component.find('.name-label').contains(props.label)).to.be.true
现在一切正常。
谢谢~!
您正在使用 shallow
渲染,这就是它失败的原因。当使用浅层渲染时,子组件不会被渲染,但会保留为组件。
所以在你的情况下,它不会进入子组件并测试 class 是否存在,而是测试渲染方法和原始组件中的直接节点而不渲染它们。
所以如果你也需要测试子组件,你需要full dom rendering