期待一个 Promise *not* 完成,在 Jest
Expecting a Promise *not* to complete, in Jest
我有以下需要测试是否没有发生。
虽然测试类似的东西可能值得讨论(等待多长时间才足够?),但我希望 Jest 中有更好的方法来集成测试超时。到目前为止,我还没有找到,但让我们从测试开始吧。
test ('User information is not distributed to a project where the user is not a member', async () => {
// Write in 'userInfo' -> should NOT turn up in project 1.
//
await collection("userInfo").doc("xyz").set({ displayName: "blah", photoURL: "https://no-such.png" });
// (firebase-jest-testing 0.0.3-beta.3)
await expect( eventually("projects/1/userInfo/xyz", o => !!o, 800 /*ms*/) ).resolves.toBeUndefined();
// ideally:
//await expect(prom).not.toComplete; // ..but with cancelling such a promise
}, 9999 /*ms*/ );
eventually
returns 一个 Promise
我想检查一下:
- 在测试的正常超时内...
- 这样的 Promise 没有完成(解决或拒绝)
Jest 提供 .resolves
和 .rejects
但没有任何东西可以将两者结合起来。
- 我可以使用一些 Jest 扩展机制创建预期的
.not.toComplete
吗?
- 我可以创建一个“运行 就在测试超时之前”(能够使测试通过或失败)触发器吗?
我认为 2.
建议可能会派上用场,并且可以为此创建一个功能请求,但让我们看看它会收到什么评论..
编辑:JS Promise 无法从外部取消(但它们可以从内部超时),这更加复杂。
我最终用自定义匹配器解决了这个问题:
/*
* test-fns/matchers/timesOut.js
*
* Usage:
* <<
* expect(prom).timesOut(500);
* <<
*/
import { expect } from '@jest/globals'
expect.extend({
async timesOut(prom, ms) { // (Promise of any, number) => { message: () => string, pass: boolean }
// Wait for either 'prom' to complete, or a timeout.
//
const [resolved,error] = await Promise.race([ prom, timeoutMs(ms) ])
.then(x => [x])
.catch(err => [undefined,err] );
const pass = (resolved === TIMED_OUT);
return pass ? {
message: () => `expected not to time out in ${ms}ms`,
pass: true
} : {
message: () => `expected to time out in ${ms}ms, but ${ error ? `rejected with ${error}`:`resolved with ${resolved}` }`,
pass: false
}
}
})
const timeoutMs = (ms) => new Promise((resolve) => { setTimeout(resolve, ms); })
.then( _ => TIMED_OUT);
const TIMED_OUT = Symbol()
好的一面是,它可以添加到任何 Jest 项目中。
不足的是,需要单独提及延迟(并保证之前不会发生Jest的超时)。
使问题代码变为:
await expect( eventually("projects/1/userInfo/xyz") ).timesOut(300)
Firebase 用户注意事项:
如果 Firestore JS SDK 客户端侦听器仍处于活动状态,Jest 不会退出到 OS 级别。您可以通过在 afterAll
中取消订阅来阻止它 - 但这意味着要跟踪哪些听众还活着,哪些不活着。 firebase-jest-testing
库在幕后为您做这件事。此外,这最终会 ;) 由 Firebase 修复。
我有以下需要测试是否没有发生。
虽然测试类似的东西可能值得讨论(等待多长时间才足够?),但我希望 Jest 中有更好的方法来集成测试超时。到目前为止,我还没有找到,但让我们从测试开始吧。
test ('User information is not distributed to a project where the user is not a member', async () => {
// Write in 'userInfo' -> should NOT turn up in project 1.
//
await collection("userInfo").doc("xyz").set({ displayName: "blah", photoURL: "https://no-such.png" });
// (firebase-jest-testing 0.0.3-beta.3)
await expect( eventually("projects/1/userInfo/xyz", o => !!o, 800 /*ms*/) ).resolves.toBeUndefined();
// ideally:
//await expect(prom).not.toComplete; // ..but with cancelling such a promise
}, 9999 /*ms*/ );
eventually
returns 一个 Promise
我想检查一下:
- 在测试的正常超时内...
- 这样的 Promise 没有完成(解决或拒绝)
Jest 提供 .resolves
和 .rejects
但没有任何东西可以将两者结合起来。
- 我可以使用一些 Jest 扩展机制创建预期的
.not.toComplete
吗? - 我可以创建一个“运行 就在测试超时之前”(能够使测试通过或失败)触发器吗?
我认为 2.
建议可能会派上用场,并且可以为此创建一个功能请求,但让我们看看它会收到什么评论..
编辑:JS Promise 无法从外部取消(但它们可以从内部超时),这更加复杂。
我最终用自定义匹配器解决了这个问题:
/*
* test-fns/matchers/timesOut.js
*
* Usage:
* <<
* expect(prom).timesOut(500);
* <<
*/
import { expect } from '@jest/globals'
expect.extend({
async timesOut(prom, ms) { // (Promise of any, number) => { message: () => string, pass: boolean }
// Wait for either 'prom' to complete, or a timeout.
//
const [resolved,error] = await Promise.race([ prom, timeoutMs(ms) ])
.then(x => [x])
.catch(err => [undefined,err] );
const pass = (resolved === TIMED_OUT);
return pass ? {
message: () => `expected not to time out in ${ms}ms`,
pass: true
} : {
message: () => `expected to time out in ${ms}ms, but ${ error ? `rejected with ${error}`:`resolved with ${resolved}` }`,
pass: false
}
}
})
const timeoutMs = (ms) => new Promise((resolve) => { setTimeout(resolve, ms); })
.then( _ => TIMED_OUT);
const TIMED_OUT = Symbol()
好的一面是,它可以添加到任何 Jest 项目中。
不足的是,需要单独提及延迟(并保证之前不会发生Jest的超时)。
使问题代码变为:
await expect( eventually("projects/1/userInfo/xyz") ).timesOut(300)
Firebase 用户注意事项:
如果 Firestore JS SDK 客户端侦听器仍处于活动状态,Jest 不会退出到 OS 级别。您可以通过在 afterAll
中取消订阅来阻止它 - 但这意味着要跟踪哪些听众还活着,哪些不活着。 firebase-jest-testing
库在幕后为您做这件事。此外,这最终会 ;) 由 Firebase 修复。