反应状态没有在笑话中更新

时间:2018-04-04 11:14:11

标签: javascript reactjs unit-testing enzyme jest

在我的反应组件中,我有两个功能。 handleChangeInput(e)在' OnChange'上调用输入字段和checkFields()的函数从handleChangeInput(e)

调用



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)
        })
	})
});
&#13;
&#13;
&#13;

但我的状态没有更新。结果,&#39; validFields&#39;未设置为true且我的第二次测试失败。我尝试了wrapper.update()和wrapper.instance()。forceUpdate()但仍然没有成功。任何帮助将不胜感激

3 个答案:

答案 0 :(得分:1)

我猜这可能是因为你用jest.fn()

覆盖了setState函数
component.setState = jest.fn()
    })

删除这个怎么样?

答案 1 :(得分:0)

希望我的回答不会太晚,但你试图以错误的方式更新状态。

首先,删除这两个:

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()
})

答案 2 :(得分:0)

我在其中一个 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()
   })
})