预期调用一个断言但收到零个断言调用。为什么?
Expected one assertion to be called but received zero assertion calls. Why?
我正在编写一个 rejectOnTimeout()
函数,如果承诺未在 ms
中完成,该函数应该 return 具有 timeout_error
值的被拒绝的承诺,或者 return 反映原始承诺行为的承诺。
我认为我得到的答案是正确的。但是我不明白错误的意思 Expected one assertion to be called but received zero assertion calls
.
在这种情况下我做错了什么?
const delay = require('delay');
/**
* @param {Promise} original promise
* @param {Number} ms for timeout
* @return {Promise}
*/
const rejectOnTimeout = (promise, ms) => new Promise((resolve, reject) => {
const start = Date.now();
promise.finally(() => {
const time = Date.now() - start;
if (time <= ms) {
resolve(promise);
}
reject('timeout_error');
});
});
// Test 1 [PASSED]
rejectOnTimeout(Promise.resolve(10), 100)
.then(data => console.log(data)) // 10
.catch(err => console.error(err));
// Test 2 [PASSED]
rejectOnTimeout(Promise.reject(10), 100)
.then(data => console.log(data))
.catch(err => console.error(err)); // 10
// Test 3 [FAILED], REASON: Expected one assertion to be called but received zero assertion calls.
const delayed = delay(100, { value: 10 });
rejectOnTimeout(delayed, 50)
.then(data => console.log(data))
.catch(err => console.error(err)); // timeout_error
测试代码:
describe('rejectOnTimeout', () => {
it('rejectOnTimeout, 01', async() => {
expect.assertions(1);
await expect(rejectOnTimeout(Promise.resolve(10), 100)).resolves.toBe(10);
});
it('rejectOnTimeout, 02', async() => {
expect.assertions(1);
await expect(rejectOnTimeout(Promise.reject(10), 100)).rejects.toBe(10);
});
it('rejectOnTimeout, 03', async() => {
expect.assertions(1);
const delayed = delay(100, { value: 10 });
await expect(rejectOnTimeout(delayed, 50)).rejects.toBe('timeout_error');
});
it('rejectOnTimeout, 04', async() => {
expect.assertions(1);
const delayed = delay.reject(100, { value: 10 });
await expect(rejectOnTimeout(delayed, 50)).rejects.toBe('timeout_error');
});
it('rejectOnTimeout, 05', async() => {
expect.assertions(1);
const delayed = delay(100, { value: 10 });
await expect(rejectOnTimeout(delayed, 1000)).resolves.toBe(10);
});
it('rejectOnTimeout, 06', async() => {
expect.assertions(1);
const delayed = delay.reject(100, { value: 'error' });
await expect(rejectOnTimeout(delayed, 1000)).rejects.toBe('error');
});
当我将您的代码插入我的编辑器时,我遇到了不同的错误:
● rejectOnTimeout › rejectOnTimeout, 03
thrown: 10
问题是之前的测试将未处理的拒绝扔到测试环境中,一切都爆炸了。将 rejectOnTimeout
实现更改为此后,所有测试都通过了:
const rejectOnTimeout = (promise, ms) =>
new Promise((resolve, reject) => {
const start = Date.now();
promise
.catch((e) => reject(e))
.finally(() => {
const time = Date.now() - start;
if (time <= ms) {
resolve(promise);
}
reject("timeout_error");
});
});
Promise.finally
并没有实际处理拒绝,它只是触发 Promise 是拒绝还是解决。因此,虽然我们在 rejectOnTimeout
中的新 Promise 可能正确完成,但未处理底层的 promise 参数。
内部捕获似乎可以保留您正在寻找的行为。如果 promise 已经抛出错误,我们大概并不关心是否有超时。 finally
中发生的事情也无关紧要,因为您无法在已经拒绝后覆盖 Promise 的结果。
以下是我将如何实现此功能:
const rejectOnTimeout = (promise, ms) => {
return new Promise((resolve, reject) => {
setTimeout(() => reject("timeout_error"), ms);
promise
.catch((e) => reject(e))
.finally(() => resolve(promise));
});
}
我正在编写一个 rejectOnTimeout()
函数,如果承诺未在 ms
中完成,该函数应该 return 具有 timeout_error
值的被拒绝的承诺,或者 return 反映原始承诺行为的承诺。
我认为我得到的答案是正确的。但是我不明白错误的意思 Expected one assertion to be called but received zero assertion calls
.
在这种情况下我做错了什么?
const delay = require('delay');
/**
* @param {Promise} original promise
* @param {Number} ms for timeout
* @return {Promise}
*/
const rejectOnTimeout = (promise, ms) => new Promise((resolve, reject) => {
const start = Date.now();
promise.finally(() => {
const time = Date.now() - start;
if (time <= ms) {
resolve(promise);
}
reject('timeout_error');
});
});
// Test 1 [PASSED]
rejectOnTimeout(Promise.resolve(10), 100)
.then(data => console.log(data)) // 10
.catch(err => console.error(err));
// Test 2 [PASSED]
rejectOnTimeout(Promise.reject(10), 100)
.then(data => console.log(data))
.catch(err => console.error(err)); // 10
// Test 3 [FAILED], REASON: Expected one assertion to be called but received zero assertion calls.
const delayed = delay(100, { value: 10 });
rejectOnTimeout(delayed, 50)
.then(data => console.log(data))
.catch(err => console.error(err)); // timeout_error
测试代码:
describe('rejectOnTimeout', () => {
it('rejectOnTimeout, 01', async() => {
expect.assertions(1);
await expect(rejectOnTimeout(Promise.resolve(10), 100)).resolves.toBe(10);
});
it('rejectOnTimeout, 02', async() => {
expect.assertions(1);
await expect(rejectOnTimeout(Promise.reject(10), 100)).rejects.toBe(10);
});
it('rejectOnTimeout, 03', async() => {
expect.assertions(1);
const delayed = delay(100, { value: 10 });
await expect(rejectOnTimeout(delayed, 50)).rejects.toBe('timeout_error');
});
it('rejectOnTimeout, 04', async() => {
expect.assertions(1);
const delayed = delay.reject(100, { value: 10 });
await expect(rejectOnTimeout(delayed, 50)).rejects.toBe('timeout_error');
});
it('rejectOnTimeout, 05', async() => {
expect.assertions(1);
const delayed = delay(100, { value: 10 });
await expect(rejectOnTimeout(delayed, 1000)).resolves.toBe(10);
});
it('rejectOnTimeout, 06', async() => {
expect.assertions(1);
const delayed = delay.reject(100, { value: 'error' });
await expect(rejectOnTimeout(delayed, 1000)).rejects.toBe('error');
});
当我将您的代码插入我的编辑器时,我遇到了不同的错误:
● rejectOnTimeout › rejectOnTimeout, 03
thrown: 10
问题是之前的测试将未处理的拒绝扔到测试环境中,一切都爆炸了。将 rejectOnTimeout
实现更改为此后,所有测试都通过了:
const rejectOnTimeout = (promise, ms) =>
new Promise((resolve, reject) => {
const start = Date.now();
promise
.catch((e) => reject(e))
.finally(() => {
const time = Date.now() - start;
if (time <= ms) {
resolve(promise);
}
reject("timeout_error");
});
});
Promise.finally
并没有实际处理拒绝,它只是触发 Promise 是拒绝还是解决。因此,虽然我们在 rejectOnTimeout
中的新 Promise 可能正确完成,但未处理底层的 promise 参数。
内部捕获似乎可以保留您正在寻找的行为。如果 promise 已经抛出错误,我们大概并不关心是否有超时。 finally
中发生的事情也无关紧要,因为您无法在已经拒绝后覆盖 Promise 的结果。
以下是我将如何实现此功能:
const rejectOnTimeout = (promise, ms) => {
return new Promise((resolve, reject) => {
setTimeout(() => reject("timeout_error"), ms);
promise
.catch((e) => reject(e))
.finally(() => resolve(promise));
});
}