这是示例实现:
export class Person extends Component {
componentDidMount() {
const { onLoadProfile, onLoadPolicy, person } = this.props
onLoadProfile(person.profile.uri)
onLoadPolicy(person.policy.uri)
}
componentDidUpdate(prevProps) {
const { onLoadProfile, onLoadPolicy, person } = this.props
const prevPerson = prevProps.person.uri
const curPerson = person.uri
// If person has changed, update Person component
if (prevPerson !== curPerson) {
onLoadProfile(person.profile.uri)
onLoadPolicy(person.policy.uri)
}
}
}
在componentDidMount()
上,我设法像这样进行测试:
describe('<Person />', () => {
let props
let mountedPerson
const mockLoadProfile = jest.fn()
const mockLoadPolicy = jest.fn()
const person = () => {
if (!mountedPerson) {
mountedPerson = mount(<Person {...props} />)
}
return mountedPerson
}
beforeEach(() => {
props = {
onLoadProfile = mockLoadProfile,
onLoadPolicy = mockLoadPolicy
}
mountedPerson = undefined
})
afterEach(() => {
mockLoadProfile.mockClear()
mockLoadPolicy.mockClear()
})
describe('componentDidMount', () => {
it('loads profile', () => {
person().instance().componentDidMount()
expect(mockLoadProfile).toBeCalled()
})
it('loads policy', () => {
person().instance().componentDidMount()
expect(mockLoadPolicy).toBeCalled()
})
})
})
在componentDidUpdate()
上,我需要该组件尝试两次render()
才能验证它是否应该在适当的时候更新,反之亦然,但是我找不到正确的方法来做吧。
在React中测试componentDidUpdate()
方法的正确方法是什么?
PS 。:我正在使用玩笑,酶和反应15 。
答案 0 :(得分:17)
我使用了不同的方法,但是您可以复制这个想法。您需要更改道具,我使用了setProps()函数:
describe('componentDidUpdate', () => {
it('loads profile', () => {
const wrapper = shallow(<Person {...props} />) as any;
wrapper.setProps({ person: { uri: "something_different" } });
expect(wrapper.instance().props.onLoadProfile).toBeCalled();
})
})
运行测试后,我可以看到componentDidUpdate中覆盖测试页面中的粉红色消失了
答案 1 :(得分:3)
公认的答案是测试上述情况的最简单方法,但是您也可以考虑从以下组件中提取componentDidUpdate
逻辑作为解决方案:
// Component definition
export class Person extends Component {
componentDidUpdate(prevProps) {
this.props.handleComponentDidUpdate(prevProps, this.currentProps)
}
// Rest of component
}
// Component functions/handlers testing
describe('Person component props', () => {
describe('handleComponentDidUpdate', () => {
it('loads profile & policy if person changes', () => {
const onLoadPolicy = jest.fn()
const onLoadProfile = jest.fn()
const prevProps = {
person: { uri: 'some-person-uri-old' },
policy: { uri: 'some-policy-uri' },
profile: { uri: 'some-profile-uri' },
onLoadPolicy,
onLoadProfile
}
const props = {
person: { uri: 'some-person-uri-new' }, // person uri changes
policy: { uri: 'some-policy-uri' },
profile: { uri: 'some-profile-uri' },
onLoadPolicy,
onLoadProfile
}
handleComponentDidUpdate(prevProps, props)
expect(onLoadPolicy).toHaveBeenCalled()
expect(onLoadProfile).toHaveBeenCalled()
})
})
})
通过这种方式,组件可以尽可能地笨拙,并且可以将应用程序逻辑提取到更易于测试的函数/处理程序中。这样,您可以将测试更多地集中在功能上(更易于测试),而将重点放在组件上(更难于测试)。
关于使用Person
组件,您只需提供所需的道具,包括handleComponentDidUpdate
。
如果仍然需要测试组件,则可以执行以下简单测试(请注意,在此测试中,与上面的功能/处理程序测试不同,我们不在乎应用程序的逻辑,例如人员,个人资料,策略等等):
// Component testing
describe('<Person/>', () => {
it('should call handleComponentDidUpdate on prop change', () => {
const handleComponentDidUpdate = jest.fn()
const prevProps = {
someProp: 'some-prop-prev',
handleComponentDidUpdate
}
const newprops = {
someProp: 'some-prop-new',
handleComponentDidUpdate
}
const wrapper = shallow(<Person { ...prevProps } />)
wrapper.setProps(newprops)
expect(handleComponentDidUpdate).toHaveBeenCalledWith(prevProps, newProps)
})
})