【问题标题】:timeout when testing promise rejection with sinon and chai-as-promise使用 sinon 和 chai-as-promise 测试承诺拒绝时超时
【发布时间】:2019-05-25 23:49:55
【问题描述】:

我有一个包装第三方child-process-promise 的函数,它本身将spawn 包装在promise 中。

let spawn = require('child-process-promise').spawn;


run(cmd, args = []) {
    return new Promise(async (resolve, reject) => {
      let command = spawn(cmd, args);
      let childProcess = command.childProcess;
      let result = '';

      childProcess.stdout.on('data', (data) => {
        result += data.toString();
      });

      try {
        const res = await command;
        resolve(result);
      } catch (err) {
        if (err.code && err.code === 'ENOENT') {
          reject(`Command "${cmd}" not found`);
        } else {
          reject('Exec err' + err);
        }
      }
    });
  }

测试解析非常简单,我设法将我的标准输出数据传递给结果,然后chai-as-promised 使用await expect(shellRun).to.eventually.become('hello world'); 检测到

我们的问题是当我们尝试测试方法的 catch 部分时。

const ERROR = 'someError';

beforeEach(() => {
    sandbox = sinon.createSandbox();

    spawnEvent = new events.EventEmitter();
    spawnEvent.stdout = new events.EventEmitter();

    spawnStub = sandbox.stub();
    spawnStub.returns({ childProcess: spawnEvent });

    spawnStub.withArgs(ERRORED, ARGUMENTS).throws(ERROR));

    shell = proxyquireStrict('../../lib/utils/spawnWrapper', {
      'child-process-promise': {
        spawn: spawnStub
      }
    }
    );
  });

  afterEach(() => {
    sandbox.restore();
  });

  describe('when a generic error occurs', () => {
    it('should reject the promise', async () => {
      const shellRun = run(ERRORED, ARGUMENTS);

      await expect(shellRun).to.eventually.be.rejectedWith('Exec err' + ERROR);
    });
  });

我们设法让childProcessPromiseSpawn 通过与 ou spawnStub.withArgs 玩有条件地抛出错误。但是遇到了超时:

(node:15425) UnhandledPromiseRejectionWarning: Error: someError
(node:15425) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 838)

1 failing

  1) run method
       when a generic error occurs
         should reject the promise:
     Error: Timeout of 2000ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves.

我们尝试了spawnStub.withArgs(ERRORED, ARGUMENTS).rejects 而不是throws,但没有取得更多成功。将someError 更改为new Error('someError') 也不起作用。

我们也尝试在测试级别赶上

try {
  await run(ERRORED, ARGUMENTS);
} catch (e) {
  expect(e).to.equal('Exec err' + ERROR);
}

但是超时还是会发生。

【问题讨论】:

  • 你试过const shellRun = await run(ERRORED..); expect(shellRun)...吗?
  • 是的,它触发了超时。请注意 await expect() 适用于解析测试。
  • 尝试返回承诺:it('should reject the promise', () => { const shellRun = run(ERRORED, ARGUMENTS); expect(shellRun).to.eventually.be.rejectedWith('Exec err' + ERROR); return shellRun; });
  • 还是一样的结果:(node:4045) UnhandledPromiseRejectionWarning: Error: someError, (node:4045) UnhandledPromiseRejectionWarning: Unhandled promise rejection
  • 您确定默认的测试超时时间足以完成您的测试吗?似乎测试由于超时而失败然后promise没有结束并且错误Unhandled promise被抛出

标签: javascript node.js chai sinon


【解决方案1】:

这取决于您使用的测试库。每个库都有一个专用的超时时间。

对于 mocha,您可以在测试套件中定义它或为一个独特的测试定义它

https://mochajs.org/#timeouts

【讨论】:

  • 超时不是问题。超时只是表明我触发的错误没有被测试框架捕获。使用 chai 和 sinon 在 mocha 上运行测试。
猜你喜欢
  • 1970-01-01
  • 2019-08-21
  • 1970-01-01
  • 2015-06-04
  • 1970-01-01
  • 1970-01-01
  • 2016-04-29
  • 2015-12-01
  • 2015-10-28
相关资源
最近更新 更多