【发布时间】: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