Jest如何基于模拟事件等待模拟调用

时间:2018-03-22 18:04:07

标签: reactjs enzyme jest

我有一个这样的测试失败因为没有调用mock,问题是模拟被调用但是在测试完成之前。

test('should submit if proper values', () => {
  const spy = jest.fn().mockReturnValue({
    data: {
      authenticateUser: {
        id: 123,
        token: 'lol'
      }
    }
  });
  mountedWrapper.setProps({
    loginMutation: spy
  });
  expect(spy).not.toHaveBeenCalled();
  email.simulate('change', {
    target: { name: 'username', value: 'email@test.com' }
  });
  password.simulate('change', {
    target: { name: 'password', value: 'secret' }
  });
  form.simulate('submit');
  expect(spy).toHaveBeenCalled();
});

但是,如果我添加以下setTimeout

,我可以通过测试
  setTimeout(() => {
    expect(spy).toHaveBeenCalled();
  }, 0);

但是我正在寻找一种更好的解决上述问题的方法。没有setTimeout的任何解决方案?

1 个答案:

答案 0 :(得分:0)

看起来你正试图测试一些异步代码。你看过this了吗?在callbacks部分,您可以找到:

  

默认情况下,Jest测试一旦到达执行结束就完成。这意味着此测试无法按预期工作:

// Don't do this!
test('the data is peanut butter', () => {
  function callback(data) {
    expect(data).toBe('peanut butter');
  }

  fetchData(callback);
});
  

问题是,在调用回调之前,一旦fetchData完成,测试就会完成。   还有一种替代形式的测试可以解决这个问题。不要将测试放在具有空参数的函数中,而是使用名为done的单个参数。 Jest将等到完成测试后调用完成回调。

test('the data is peanut butter', done => {
  function callback(data) {
    expect(data).toBe('peanut butter');
    done();
  }

  fetchData(callback);
});
  

如果从未调用done(),则测试将失败,这就是您想要发生的事情。

这是callback的示例,但您也可以使用promises.resolves/.rejectsasync/await