开玩笑:测试不能在 setImmediate 或 process.nextTick 回调中失败 [英] Jest: tests can't fail within setImmediate or process.nextTick callback

查看:13
本文介绍了开玩笑:测试不能在 setImmediate 或 process.nextTick 回调中失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试为需要在其 componentWillMount 方法中完成异步操作的 React 组件编写测试.componentWillMount 调用一个函数,作为一个 prop 传递,它返回一个 Promise,我在测试中模拟了这个函数.

I'm trying to write a test for a React component that needs to complete an asynchronous action in its componentWillMount method. componentWillMount calls a function, passed as a prop, which returns a promise, and I mock this function in my test.

这很好用,但如果在调用 setImmediateprocess.nextTick 时测试失败,则 Jest 不会处理该异常并提前退出.下面,你可以看到我什至试图捕捉这个异常,但无济于事.

This works fine, but if a test fails in a call to setImmediate or process.nextTick, the exception isn't handled by Jest and it exits prematurely. Below, you can see I even try to catch this exception, to no avail.

如何在 Jest 中使用 setImmediatenextTick 之类的东西?这个问题的公认答案是我试图实现的失败:React Enzyme - Test`componentDidMount` 异步调用.

How can I use something like setImmediate or nextTick with Jest? The accepted answer to this question is what I'm trying to implement unsuccessfully: React Enzyme - Test `componentDidMount` Async Call.

it('should render with container class after getting payload', (done) => {
  let resolveGetPayload;
  let getPayload = function() {
    return new Promise(function (resolve, reject) {
      resolveGetPayload = resolve;
    });
  }
  const enzymeWrapper = mount(<MyComponent getPayload={getPayload} />);

  resolveGetPayload({
    fullname: 'Alex Paterson'
  });

  try {
    // setImmediate(() => {
    process.nextTick(() => {
      expect(enzymeWrapper.hasClass('container')).not.toBe(true); // Should and does fail
      done();
    });
  } catch (e) {
    console.log(e); // Never makes it here
    done(e);
  }
});

Jest v18.1.0

Jest v18.1.0

节点 v6.9.1

推荐答案

另一个可能更干净的解决方案,使用 async/await 并利用 jest/mocha 的能力来检测返回的 Promise:

Another potentially cleaner solution, using async/await and leveraging the ability of jest/mocha to detect a returned promise:

// async test utility function
function currentEventLoopEnd() {
  return new Promise(resolve => setImmediate(resolve));
}

it('should render with container class after getting payload', async () => {
  
  // mock the API call in a controllable way,
  // starts out unresolved
  let resolveGetPayload; // <- call this to resolve the API call
  let getPayload = function() {
    return new Promise(function (resolve, reject) {
      resolveGetPayload = resolve;
    });
  }
  
  // instanciate the component under state with the mock
  const enzymeWrapper = mount(<MyComponent getPayload={getPayload} />);
  expect(enzymeWrapper.hasClass('container')).not.toBe(true);

  resolveGetPayload({
    fullname: 'Alex Paterson'
  });

  await currentEventLoopEnd(); // <-- clean and clear !

  expect(enzymeWrapper.hasClass('container')).toBe(true);
});

这篇关于开玩笑:测试不能在 setImmediate 或 process.nextTick 回调中失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆