首页 > 解决方案 > 使用 sinon 和 chai-as-promise 测试承诺拒绝时超时

问题描述

我有一个包装第三方的功能child-process-promise,它本身包装spawn在承诺中。

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没有更多的成功。更改someErrornew Error('someError')也不起作用。

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

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

但是超时仍然发生。

标签: javascriptnode.jschaisinon

解决方案


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

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

https://mochajs.org/#timeouts


推荐阅读