![](/img/trans.png)
[英]How to write unit test for DataTable in React Component using Enzyme with Jest?
[英]Can we skip a react hook (getderivedstatefromprops) while unit test of a component using Enzyme and jest
我正在编写一个Counter组件,其初始状态设置为零,并且从父组件接收到新状态,而在单元测试中模拟增量或减量功能时,由于“ getderivedstatefromprops”钩子,更改后的状态被父项初始状态覆盖。 在组件中,它仅被调用一次,但是在单元测试中,当我们在模拟增量函数后更新组件实例时,它会接收初始值并将状态更改为初始状态。 这在创建组件实例时有什么办法吗?
export default class Counter extends React.Component<CounterProps,
CounterState> {
state = {
value: 0,
}
static getDerivedStateFromProps(props, state) {
return { ...state, value: props.initialValue }
}
incrementCounter = () => {
const { value } = this.state
const { id, maxValue, countChangeHandler, isDisabled } = this.props
const newValue = value + 1
if (newValue <= maxValue) {
countChangeHandler(id, newValue)
}
this.setState({ value: newValue })
}
render() {
const { value } = this.state
const { maxValue, isDisabled } = this.props
return (
<StyledCounter>
<Count disabled={isDisabled}>{value}</Count>
<Action onClick={this.incrementCounter}>
<Icon shape="plusGray" size="20px" />
</Action>
<Label>{'max ' + maxValue}</Label>
</StyledCounter>
)}
}
单元测试:
describe('Counter components', () => {
function renderCounter(customProperties = {}) {
const properties = {
id: 124355,
initialValue: 3,
maxValue: 5,
isDisabled: false,
countChangeHandler: jest.fn(),
...customProperties,
}
const { output } = renderComponent(<Counter {...properties} />)
return output
}
afterEach(() => {
jest.resetAllMocks()
})
it('On multiple click on Increment button, counter value should not exceed max value.', () => {
const component = renderCounter()
component.find('div#increment').simulate('click')
component.find('div#increment').simulate('click')
component.find('div#increment').simulate('click')
component.find('Counter').update()
expect(component.find(Counter).state('value')).toEqual(5)
})
})
renderComponent正在使用Mount。 单元测试未能达到预期的5,但收到了3。
因此,当组件本身不更新其某些状态并应依靠父级时,您的组件就像React中的controlled input
模式。
我相信您不需要任何特殊技巧就可以对其进行测试。 我在这里测试的是:
props.value
会影响render
结果 props.value + 1
调用props.countChangeHandler
,而小于props.maxValue
props.countChangeHandler
在所有如果它超过props.maxValue
const countChangeHandlerMocked = jest.fn();
function createCounter({ initialValue, maxValue }) {
return shallow(<Counter
initialValue={initialValue}
maxValue={maxValue}
id="mock_id"
countChangeHandler={countChangeHandlerMocked}
/>);
}
it('renders props.value as a Count`, () => {
const wrapper = createCounter({initialValue: 42, maxValue: 100});
expect(wrapper.find(Count).props().children).toEqual(42);
expect(countChangeHandlerMocked).not.toHaveBeenCalled();
});
it('keeps Count in sync with props.value on update', () => {
const wrapper = createCounter({initialValue: 42, maxValue: 100});
wrapper.setProps({ initialValue: 43 });
expect(wrapper.find(Count).props().children).toEqual(43);
expect(countChangeHandlerMocked).not.toHaveBeenCalled();
});
it('reacts on button click if value< maxValue', () => {
const wrapper = createCounter({ initialValue: 1, maxValue: 10 });
wrapper.find(Action).props().onClick();
expect(countChangeHandlerMocked).toHaveBeenCalledWith('mocked_id', 2);
});
it('does not react on button click if value == maxValue', () => {
const wrapper = createCount({ initialValue: 10, maxValue: 10 });
wrapper.find(Action).props().onClick();
expect(countChangeHandlerMocked).not.toHaveBeenCalled();
})
看,您越依赖state
或生命周期方法等实现细节,测试就变得越脆弱。 像上面说的那样进行测试,很容易将组件重构为一个功能或多个功能的组合(只是也许我们需要使用mount()
而不是shallow
),并且组件和测试都可以。 相反,过分地依赖实现细节会导致您的测试失败,即使在进行了合法更改之后(例如删除gDSFP
并在render()
使用props.initialValue
而不是state.value
)。
是否有意义?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.