【问题标题】:Jest/enzyme: How to test for .then and .catch of an nested asynchronous functionJest/enzyme:如何测试嵌套异步函数的 .then 和 .catch
【发布时间】:2018-04-23 04:22:28
【问题描述】:

我正在尝试对我的 reactJS 组件中的异步函数进行一些酶/开玩笑单元测试,该函数作为 prop 注入。

我的问题是测试函数的then() 部分中的值,如果发生错误,则测试catch()

我的组件 (<CreateAccount />) 的功能如下所示:

_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) {
      Cookies.set('auth-token', token, { expires: 1 })
    }
  }).catch(error => {
    console.warn(error)
  })
}

第一个测试应该检查.catch(error => {}),因为数据未定义:

it('_onSubmit() should throw error if data is missing', () => {
  const createUserMutation = () => {
    return Promise.resolve({})
  }
  const wrapper = shallow(<CreateAccount createUserMutation={createUserMutation} />)
  wrapper.update().find(Form).simulate('submit', {
    preventDefault: () => {}
  })
  const state = wrapper.instance().state
  expect(wrapper).toThrow() // <-- How to do it correctly?
})

第二个测试应该检查cookie是否设置正确。在这里我不知道该怎么做?我想我必须嘲笑Cookie

it('_onSubmit() should get token', () => {
  const createUserMutation = () => {
    return Promise.resolve({
      data: {
        createUser: { token: 'token' }
      }
    })
  }
  const wrapper = shallow(<CreateAccount createUserMutation={createUserMutation} />)
  wrapper.find(Form).simulate('submit', {
    preventDefault: () => {}
  })
  // How to check for token value and Cookies?
})

【问题讨论】:

    标签: javascript reactjs unit-testing asynchronous enzyme


    【解决方案1】:

    当我想查看 spy 是否在 catch 或 then 上工作时,我通常要做的就是在测试中添加另一个 then()。例如:

    it('_onSubmit() should throw error if data is missing', () => {
      const createUserMutation = jest.fn(() => Promise.reject(new Error()));
      const spy = jest.spyOn(console,"warn");
      const wrapper = shallow(<CreateAccount createUserMutation={createUserMutation} />)
      wrapper.update().find(Form).simulate('submit', {
        preventDefault: () => {}
      });
      return createUserMutation.catch(() => {
        expect(wrapper).toMatchSnapshot();
    })
    .then(() => {
      expect(spy).toHaveBeenCalledTimes(1);
    });
    })
    

    我猜这与 NodeJS 如何在内部处理队列、promise、tick 等有关。

    那是被拒绝/捕获的分支。如果要测试 IF 路径,只需使用 Promise.resolve 并返回 promise.then() 而不是 catch。

    【讨论】:

    • 感谢您的意见。好的。会试一试的。
    【解决方案2】:

    您为什么使用console.warn 来表示错误?请改用console.error。您还需要将其模拟给间谍以进行测试。

    第一次测试:

    it('_onSubmit() should throw error if data is missing', (done) => {
      const createUserMutation = () => new Promise();
      const wrapper = shallow(<CreateAccount createUserMutation={createUserMutation} />)
      wrapper.update().find(Form).simulate('submit', {
        preventDefault: () => {}
      })
    
      const state = wrapper.instance().state
    
      createUserMutation.resolve().then(() => {
        expect(console.warn).toHaveBeenCalled();
        done();
      });
    })
    

    如果您在模拟浏览器环境而不是真正的浏览器中运行它,那么您必须模拟出Cookies.set

    第二次测试:

    it('_onSubmit() should get token', (done) => {
      const createUserMutation = () => new Promise();
      const wrapper = shallow(<CreateAccount createUserMutation={createUserMutation} />)
    
      wrapper.find(Form).simulate('submit', {
        preventDefault: () => {}
      });
    
      jest.spyOn(window.Cookies, 'set');
    
      const response  = {
          data: {
            createUser: { token: 'token' }
          }
      }
    
      createUserMutation.resolve(response).then(() => {
        expect(window.Cookies.set).toHaveBeenCalled();
        done();
      });
    })
    
    afterEach(() => {
        // Reset the spies so that they don't leak to other tests
        jest.restoreAllMocks();
    });
    

    【讨论】:

    • 我确实收到了两个测试的错误TypeError: Promise resolver undefined is not a function
    猜你喜欢
    • 2019-05-01
    • 1970-01-01
    • 2019-06-25
    • 2019-01-04
    • 2018-08-31
    • 2018-12-23
    • 2018-10-31
    • 1970-01-01
    • 2020-03-08
    相关资源
    最近更新 更多