Jest / enzyme:如何测试嵌套异步函数的.then和.catch

时间:2017-11-10 01:22:41

标签: javascript reactjs unit-testing asynchronous enzyme

我正在尝试对我的reactJS组件中的异步函数进行一些酶/ jest单元测试,该组件将作为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?
})

2 个答案:

答案 0 :(得分:1)

当我想看看间谍是否对捕获工作时,我通常要做的是在测试中添加另一个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如何在内部处理队列,承诺,滴答等有关。

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

答案 1 :(得分:0)

为什么使用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();
});
相关问题