简体   繁体   中英

ReactJS/Enzyme: How to test a submit function, which calls a graphQL mutation via prop

I'm trying to write a unit test (enzyme/jest) for this function:

_onSubmit = (event) => {
  event.preventDefault()
  const { username, password } = this.state

  this.props.createUserMutation({
    variables: { username, password }
  }).then(response => {
    const token = response.data.createUser.token
    if (token) {
        this.setState({ token })
    }
  }).catch(error => {
    console.warn(error)
  })
}

But I don't know how to handle this.props.createUserMutation() for proper testing.

Of course my current attempt throws a TypeError: _this.props.createUserMutation is not a function error

Unit test

it('_onSubmit() should submit form and reset state object', () => {
  const wrapper = shallow(<CreateAccount />)
  wrapper.setState({ username: 'Username', password: 'Password' })
  wrapper.find(Form).simulate('submit', {
    preventDefault: () => {}
  })
  const state = wrapper.instance().state
  expect(state).toEqual({ token: 'test' })
})

Updated unit test

it('_onSubmit() should submit data and get result dataset', () => {
    const createUserMutation = () => {
      return Promise.resolve({
        data: {
          createUser: { token: 'token' }
        }
      })
    }
    const wrapper = shallow(<CreateAccount createUserMutation={createUserMutation} />)
    wrapper.find(Form).simulate('submit', {
      preventDefault: () => {}
    })
    const state = wrapper.instance().state
    expect(state).toEqual({ token: 'token' })
  })

console.log(state) doesn't give me a token .

I'm assuming createUserMutation is injected to props by the compose function.

So, what you can do is import the non-default component in your test instead of the 'connected' one.

import {CreateAccount} from './CreateAcount';

Then, you can pass createUserMutation as props directly to the component when mounting it.

it('_onSubmit() should submit form and reset state object', () => {
  const createUserMutation = () => {
      return Promise.resolve({
           username: '',
           password: ''
         });
  };
  const wrapper = shallow(<CreateAccount createUserMutation={createUserMutation} />)
   ...
});

Given that createUserMutation seems to be a function that returns a promise, you can assign it Promise.resolve() in order to execute the then function which changes the state. Which is basically what you are testing.

Moreover, you're not able to test the token change in the state because the verification in the test is being run before the state changing in the method _onSubmit . (You can check this by putting console statements in both places and see which executes first).

What you need to do is return the promise in your _onSubmit method.

_onSubmit = (event) => {
  event.preventDefault()
  const { username, password } = this.state

  return this.props.createUserMutation({   // returning the promise
    variables: { username, password }
  }).then(response => {
    const token = response.data.createUser.token
    if (token) {
        this.setState({ token })
    }
  }).catch(error => {
    console.warn(error)
  })
}

Then, in your unit test you need to simulate the submit event by calling the function directly from props in order to put your verifications inside a then function. By doing this, you would run your expect statement after the state has been changed.

it('_onSubmit() should submit data and get result dataset', () => {
    const createUserMutation = () => {
      return Promise.resolve({
        data: {
          createUser: { token: 'token' }
        }
      })
    }
    const wrapper = shallow(<CreateAccount createUserMutation={createUserMutation} />)
    wrapper.find(Form).props().onSubmit({
      preventDefault: () => {}
    }).then(() =< {
       const state = wrapper.instance().state
       expect(state).toEqual({ token: 'token' })
    })
  })

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM