[英]react state is not updating in jest
在我的反应组件中,我有两个功能。 在输入字段的“OnChange”上调用 handleChangeInput(e),从 handleChangeInput(e) 调用 checkFields()
constructor(){ super() this.state={ email: '', password:'', validFields: false } } handleChangeInput(e){ const name = e.target.name; const value = e.target.value; this.setState({[name]: value},()=>{ this.checkFields(); }); } checkFields(){ if (this.state.email.length>0 && this.state.password.length>0 ) { this.setState({validFields: true}); }else { this.setState({validFields: false}); } }
在我的 index.test.js 我有
describe('<Login />', () => { describe('handleChangeInput', () => { const component = new Login() const wrapper = shallow(<Login />); beforeEach(() => { component.setState = jest.fn() }) test('calls setState validFields false when no email/password', () => { const state = { state : { email: '', password: ''} } const args = { target : { name: 'name', value: 'value' } } component.handleChangeInput.call(state, args) expect(component.setState.mock.calls.length).toBe(1) expect(wrapper.state().validFields).toEqual(false) }) test('calls setState validFields true when email/password are ok', () => { const state = { state : { email: 'email', password: 'password' } } const args = { target : { name: 'name', value: 'value' } } component.handleChangeInput.call(state, args) expect(component.setState.mock.calls.length).toBe(1) expect(wrapper.state().validFields).toEqual(false) }) }) });
但是我的状态没有被更新。 结果,'validFields' 未设置为 true,我的第二个测试失败。 我尝试了 wrapper.update() 和 wrapper.instance().forceUpdate() 但仍然没有成功。 任何帮助将不胜感激
我猜这可能是因为你用 jest.fn() 覆盖了 setState 函数
component.setState = jest.fn()
})
去掉这个怎么样?
希望我的回答不会太晚,但您正试图以错误的方式更新状态。
首先,删除这两个:
const component = new Login()
beforeEach(() => {
component.setState = jest.fn()
})
很可能你想改变这个:
handleChangeInput(e){
const name = e.target.name;
const value = e.target.value;
this.setState({[name]: value},()=>{
this.checkFields();
});
}
handleChangeInput(e){
const name = e.target.name;
const value = e.target.value;
this.setState(()=>{
return { email: name}
});
this.setState(()=>{
return { password: value }
});
this.checkFields();
}
const component = new Login() 不会为该测试带来任何价值,如果您希望 setState 实际已更改,则不应模拟它。
相反,您应该测试实际组件(就像您在这里已经部分完成的那样)
像这样更改代码:
test('calls setState validFields true when email/password are ok', () => {
const args = { target : { email: 'email', password: 'password' } }
wrapper.instance().handleChangeInput(args)
expect(wrapper.state('email')).toEqual('email')
expect(wrapper.state('password')).toEqual('password')
expect(wrapper.state('validFields')).toBeTruthy()
})
我在其中一个 git 论坛中找到了这个答案。 它对我有用。
// somewhere in your test setup code
global.flushPromises = () => {
return new Promise(resolve => setImmediate(resolve))
}
test('something with unreachable promises', () => {
expect.hasAssertions()
const component = mount(<Something />)
// do something to your component here that waits for a promise to return
return flushPromises().then(() => {
component.update() // still may be needed depending on your implementation
expect(component.html()).toMatchSnapshot()
})
})
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.