Jest & Firebase Emulator - 等待触发函数被调用



我的package.json文件包含以下内容:

...
"jest": "jest --runInBand",
"test": "firebase emulators:exec 'npm run jest'"
...

这使我能够在运行Firebase Emulator的情况下运行基于CCD_ 2的测试。

考虑以下代码:

describe("MyTests", () => {
const req = supertest(app);
let user: admin.auth.UserRecord;
let idToken: string | undefined;
beforeAll(async () => {
const email = "test@gmail.com";
const password = "password";
user = await admin.auth().createUser({ email: email, password: password });
await auth.signInWithEmailAndPassword(email, password);
idToken = await auth.currentUser?.getIdToken();
});
// actual tests

在这里,我创建了一个Firebase用户,它反过来触发了一个函数(functions.auth.user().onCreate(foo)(。

我确实注意到这个foo函数是在之后执行的,jest测试套件正在运行:

Test Suites: 1 passed, 1 total
Tests:       3 passed, 3 total
Snapshots:   0 total
Time:        14.841 s, estimated 16 s
Ran all test suites.
✔  Script exited successfully (code 0)
i  functions: Beginning execution of "us-central1-foo"
i  emulators: Shutting down emulators.
i  functions: Stopping Functions Emulator
i  functions: Waiting for all functions to finish...
i  functions: Finished "us-central1-foo" in ~1s

如何在beforeAll()函数内部等待它的执行?

我找到了一个非常巧妙的解决方案来实现这一点,但它确实有效

当我自己研究这个问题时,我意识到Emulator UI中的日志可以在ws://localhost:4500上的websocket上获得

因此,我所做的是创建了一个函数,根据firebase日志Beginning execution of "Finished "检查函数何时开始和何时结束

我还创建了一个函数,它添加了一个监听器,当从最后一个Finished "消息起100毫秒内没有触发任何函数时,该监听器就会被触发

Emulator UI默认情况下不包含在firebase emulators:exec-命令中,因此您需要将其与firebase emulators:exec --ui "npm test"一起运行才能启动日志服务。

我像这个一样使用它

beforeAll(async () => {
await initFirebaseListener()
})
afterAll(() => {
closeSocket()
})
describe('wait for firebase', () => {
test('should wait for firebase', async () => {
// do stuff that triggers some auth, firestore, RTDB or whatever function
await waitForFirebaseToFinish()
// Get something that i can validate
// expect(theThingIWasWaitingFor).toEqual('the expected value that the trigged did')
})
})

主要收获:

  • 您需要关闭套接字,以便在测试执行后终止进程
  • 这是超级黑客,可以在firebase管理员的下一次更新中破解
  • 您需要将--ui添加到emulators:exec命令中,日志服务才能启动
  • 至少对我来说是有效的

用代码创建了一个要点,链接如下。我使用websocket npm库(npm install -D websocket(订阅日志,但如果您愿意,也可以使用其他库。

https://gist.github.com/Gurey/8301022f8357b3a7d74cefca4b598646

最新更新