如何使用jest在一定量的模拟时间后运行断言测试?

时间:2016-11-22 21:00:17

标签: javascript unit-testing reactjs jestjs enzyme

假设我有一个Component,它呈现一个简单的div,其中包含一个从0开始并每秒加1的整数。因此,在5秒后,组件应该呈现" 5" 30秒后,它应该呈现" 30"等等。如果我想测试这个组件并确保它在5秒后呈现它应该是什么,我可能会写这样的东西。

it('should render <5> after 5 seconds', () => {
  const time = mount(<Timer/>)
  setTimeout(() => {
    expect(time.text()).toEqual('5')
  }, 5000)
})

然而,这并不起作用,因为测试从未实际运行期望并且无论如何都返回通过。即使它确实有效,使用这样的超时也会非常低效,因为测试必须等待5秒。如果我想模拟更长的时间怎么办?在做了一些搜索之后,我发现jest实际上有一个timer mock,但我似乎无法弄清楚如何在这种情况下实现它。任何帮助将不胜感激。谢谢!

2 个答案:

答案 0 :(得分:1)

为了让Jest知道你的测试是异步的,你需要:1)返回一个Promise,或者2)在测试回调中声明一个参数,如下所示:

it('should render <5> after 5 seconds', done => {
  // test stuff
});

来源:https://facebook.github.io/jest/docs/en/asynchronous.html

让测试工作:

it('should render <5> after 5 seconds', done => {
  jest.useFakeTimers(); // this must be called before any async things happen

  const time = mount(<Timer/>);

  setTimeout(() => {
    // Note the placement of this try/catch is important.
    // You'd think it could be placed most anywhere, but nope...
    try {
      // If this assertion fails, an err is thrown.
      // If we do not catch()...done.fail(e) it,
      // then this test will take jasmine.DEFAULT_TIMEOUT_INTERVAL (5s unless you override)
      // and then fail with an unhelpful message.
      expect(time.text()).toEqual('5');
      done();
    } catch(e) {
      done.fail(e);
    }
  }, 5000);
  jest.runTimersToTime(5000); // This basically fast forwards 5s.
});

答案 1 :(得分:0)

你必须在'require'你的组件之前调用jest.useFakeTimers();来模拟setTimeout。

  

这里我们通过调用jest.useFakeTimers();来启用伪计时器。这个   使用模拟函数模拟setTimeout和其他计时器函数。

要测试异步工作流程Jest documentation says,您必须为每个'it'函数回调返回Promise

  

要测试异步函数,只需从中返回一个promise。什么时候   运行测试,Jest将等待承诺解决之前   让测试完成。您也可以从中返回承诺   beforeEach,afterEach,beforeAll或afterAll functions。例如,   假设fetchBeverageList()返回应该承诺的promise   解析为其中包含柠檬的列表。你可以用以下方法测试:

所以你可以这样写:

it('should render <5> after 5 seconds', () => {
  jest.useFakeTimers();
  //only after that, require your componenet
  let Timer = require('./timer');
  const time = mount(<Timer/>);
  jest.runAllTimers();
  expect(setTimeout.mock.calls.length).toBe(1);
  expect(setTimeout.mock.calls[0][1]).toBe(5000);
  expect(time.text()).toEqual('5');
})